Commit 76a66fcf authored by Kunshan Wang's avatar Kunshan Wang

Fixed pinning and osr tests.

parent ffdc3604
...@@ -6,6 +6,7 @@ $SED -i 's/newClientAgent/newContext/g' $FN ...@@ -6,6 +6,7 @@ $SED -i 's/newClientAgent/newContext/g' $FN
$SED -i 's/deleteHandle/deleteValue/g' $FN $SED -i 's/deleteHandle/deleteValue/g' $FN
$SED -i 's/\bca\b/ctx/g' $FN $SED -i 's/\bca\b/ctx/g' $FN
$SED -i 's/ctx\.close()/ctx.closeContext()/g' $FN $SED -i 's/ctx\.close()/ctx.closeContext()/g' $FN
$SED -i 's/Handle/MuValue/g' $FN
$SED -i 's/putInt("@i32",/handleFromInt32(/g' $FN $SED -i 's/putInt("@i32",/handleFromInt32(/g' $FN
$SED -i 's/putInt("@i64",/handleFromInt64(/g' $FN $SED -i 's/putInt("@i64",/handleFromInt64(/g' $FN
$SED -i 's/putInt("@i\(\d\+\)"\s*,\s*\([^)]*\))/handleFromInt(\2, \1)/g' $FN $SED -i 's/putInt("@i\(\d\+\)"\s*,\s*\([^)]*\))/handleFromInt(\2, \1)/g' $FN
...@@ -15,8 +16,10 @@ $SED -i 's/putConstant/handleFromConst/g' $FN ...@@ -15,8 +16,10 @@ $SED -i 's/putConstant/handleFromConst/g' $FN
$SED -i 's/putGlobal/handleFromGlobal/g' $FN $SED -i 's/putGlobal/handleFromGlobal/g' $FN
$SED -i 's/putFunction/handleFromFunc/g' $FN $SED -i 's/putFunction/handleFromFunc/g' $FN
$SED -i 's/toInt(\(\w\+\),\s*\(signExt\s*=\s*\)\?true)/handleToSInt(\1.asInstanceOf[MuIntValue])/g' $FN $SED -i 's/toInt(\(\w\+\),\s*\(signExt\s*=\s*\)\?true)/handleToSInt(\1.asInstanceOf[MuIntValue])/g' $FN
$SED -i 's/toInt(\(\w\+\))/handleToUInt(\1.asInstanceOf[MuIntValue])/g' $FN
$SED -i 's/toFloat/handleToFloat/g' $FN $SED -i 's/toFloat/handleToFloat/g' $FN
$SED -i 's/toDouble/handleToDouble/g' $FN $SED -i 's/toDouble/handleToDouble/g' $FN
$SED -i 's/toPointer/handleToPtr/g' $FN
$SED -i 's/refCast/refcast/g' $FN $SED -i 's/refCast/refcast/g' $FN
$SED -i 's/currentInstruction/curInst/g' $FN $SED -i 's/currentInstruction/curInst/g' $FN
$SED -i 's/TrapRebindPassVoid/returnFromTrap/g' $FN $SED -i 's/TrapRebindPassVoid/returnFromTrap/g' $FN
......
FN=$1 FN=$1
if [ x$SED == x ]; then
sed -i 's/\(%\w\+\)\s*=\s*TRAP/[\1] TRAP/g' $FN SED=sed
sed -i 's/NEWSTACK\s*<\(@\w\+\)>\s*\(@\w\+\)/COMMINST @uvm.new_stack <[\1]> (\2)/g' $FN fi
sed -i 's/COMMINST\s*@uvm\.new_thread\s*(\([@%]\w\+\))/NEWTHREAD \1 PASS_VALUES /g' $FN $SED -i 's/\(%\w\+\)\s*=\s*TRAP/[\1] TRAP/g' $FN
sed -i 's/TRAP\s*<@void>/TRAP <>/g' $FN $SED -i 's/NEWSTACK\s*<\(@\w\+\)>\s*\(@\w\+\)/COMMINST @uvm.new_stack <[\1]> (\2)/g' $FN
sed -i 's/noparamsnoret/v_v/g' $FN $SED -i 's/COMMINST\s*@uvm\.new_thread\s*(\([@%]\w\+\))/NEWTHREAD \1 PASS_VALUES /g' $FN
sed -i 's/@void\s*(\([^)]*\))/(\1) -> ()/g' $FN $SED -i 's/TRAP\s*<@void>/TRAP <>/g' $FN
$SED -i 's/noparamsnoret/v_v/g' $FN
$SED -i 's/@void\s*(\([^)]*\))/(\1) -> ()/g' $FN
...@@ -26,65 +26,65 @@ class ObjectPinningTest extends UvmBundleTesterBase { ...@@ -26,65 +26,65 @@ class ObjectPinningTest extends UvmBundleTesterBase {
microVM.memoryManager.heap.space.debugLogBlockStates() microVM.memoryManager.heap.space.debugLogBlockStates()
preloadBundles("tests/uvm-refimpl-test/uvm-mem-test-bundle.uir") preloadBundles("tests/uvm-refimpl-test/primitives.uir", "tests/uvm-refimpl-test/uvm-mem-test-bundle.uir")
microVM.memoryManager.heap.space.debugLogBlockStates() microVM.memoryManager.heap.space.debugLogBlockStates()
behavior of "The garbage collector" behavior of "The garbage collector"
it should "not collect pinned objects." in { it should "not collect pinned objects." in {
val ca = microVM.newClientAgent() val ctx = microVM.newContext()
val hRefsKeep = new ArrayBuffer[Handle] val hRefsKeep = new ArrayBuffer[MuValue]
val hRefsPin = new ArrayBuffer[Handle] val hRefsPin = new ArrayBuffer[MuValue]
val hPtrsPin = new ArrayBuffer[Handle] val hPtrsPin = new ArrayBuffer[MuValue]
val addrsPin = new ArrayBuffer[Word] val addrsPin = new ArrayBuffer[Word]
val keepPer = 1000 val keepPer = 1000
val pinPer = 6000 val pinPer = 6000
for (i <- 0 until 20000) { for (i <- 0 until 20000) {
val hRef = ca.newFixed("@i64") val hRef = ctx.newFixed("@i64")
if (i % keepPer == 0) { if (i % keepPer == 0) {
hRefsKeep += hRef hRefsKeep += hRef
if (i % pinPer == 0) { if (i % pinPer == 0) {
val hPtr = ca.pin(hRef) val hPtr = ctx.pin(hRef)
val addr = ca.toPointer(hPtr) val addr = ctx.handleToPtr(hPtr)
hRefsPin += hRef hRefsPin += hRef
hPtrsPin += hPtr hPtrsPin += hPtr
addrsPin += addr addrsPin += addr
} }
} else { } else {
ca.deleteHandle(hRef) ctx.deleteValue(hRef)
} }
} }
gc() gc()
val addrs2Pin = hRefsPin.map { h => val addrs2Pin = hRefsPin.map { h =>
val hPtr2 = ca.pin(h) val hPtr2 = ctx.pin(h)
val addr2 = ca.toPointer(hPtr2) val addr2 = ctx.handleToPtr(hPtr2)
addr2 addr2
} }
addrsPin shouldEqual addrs2Pin addrsPin shouldEqual addrs2Pin
for (hRef <- hRefsPin) { for (hRef <- hRefsPin) {
ca.unpin(hRef) ctx.unpin(hRef)
ca.unpin(hRef) ctx.unpin(hRef)
} }
gc() gc()
for (hRef <- hRefsKeep) { for (hRef <- hRefsKeep) {
ca.deleteHandle(hRef) ctx.deleteValue(hRef)
} }
gc() gc()
ca.close() ctx.closeContext()
} }
} }
\ No newline at end of file
...@@ -11,6 +11,8 @@ import uvm.refimpl.mem._ ...@@ -11,6 +11,8 @@ import uvm.refimpl.mem._
import MemoryOrder._ import MemoryOrder._
import AtomicRMWOptr._ import AtomicRMWOptr._
import uvm.refimpl.mem.TypeSizes.Word import uvm.refimpl.mem.TypeSizes.Word
import uvm.refimpl.TrapHandlerResult.{ ThreadExit, Rebind }
import uvm.refimpl.HowToResume.{ PassValues, ThrowExc }
import ch.qos.logback.classic.Level._ import ch.qos.logback.classic.Level._
...@@ -25,111 +27,111 @@ class UvmOSRTests extends UvmBundleTesterBase { ...@@ -25,111 +27,111 @@ class UvmOSRTests extends UvmBundleTesterBase {
"tests/uvm-refimpl-test/osr-tests.uir") "tests/uvm-refimpl-test/osr-tests.uir")
"Stack introspection" should "see functions and keepalive value in all frames" in { "Stack introspection" should "see functions and keepalive value in all frames" in {
val ca = microVM.newClientAgent() val ctx = microVM.newContext()
val func = ca.putFunction("@intro_test_base") val func = ctx.handleFromFunc("@intro_test_base")
val arg0 = ca.putInt("@i64", 3) val arg0 = ctx.handleFromInt64(3)
testFunc(ca, func, Seq(arg0)) { (ca, th, st, wp) => testFunc(ctx, func, Seq(arg0)) { (ctx, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) match { nameOf(ctx.curInst(st, 0)) match {
case "@intro_rec_v1.zero.trap_rec" => { case "@intro_rec_v1.zero.trap_rec" => {
val Seq(n0) = ca.dumpKeepalives(st, 0) val Seq(n0) = ctx.dumpKeepalives(st, 0)
ca.toInt(n0) shouldBe 0 ctx.handleToUInt(n0.asInstanceOf[MuIntValue]) shouldBe 0
for (i <- 1 to 3) { for (i <- 1 to 3) {
nameOf(ca.currentInstruction(st, i)) shouldBe "@intro_rec_v1.nz.rv" nameOf(ctx.curInst(st, i)) shouldBe "@intro_rec_v1.nz.call"
val Seq(ni, nm1i) = ca.dumpKeepalives(st, i) val Seq(ni, nm1i) = ctx.dumpKeepalives(st, i)
ca.toInt(ni) shouldBe i ctx.handleToUInt(ni.asInstanceOf[MuIntValue]) shouldBe i
ca.toInt(nm1i) shouldBe (i - 1) ctx.handleToUInt(nm1i.asInstanceOf[MuIntValue]) shouldBe (i - 1)
} }
nameOf(ca.currentInstruction(st, 4)) shouldBe "@intro_test_base_v1.entry.rv" nameOf(ctx.curInst(st, 4)) shouldBe "@intro_test_base_v1.entry.call"
TrapRebindPassValue(st, n0) Rebind(st, PassValues(Seq(n0)))
} }
} }
} }
ca.close() ctx.closeContext()
} }
"@sum" should "give the sum when n < 5" in { "@sum" should "give the sum when n < 5" in {
val ca = microVM.newClientAgent() val ctx = microVM.newContext()
val func = ca.putFunction("@osr_test_base") val func = ctx.handleFromFunc("@osr_test_base")
val arg0 = ca.putInt("@i64", 4) val arg0 = ctx.handleFromInt64(4)
testFunc(ca, func, Seq(arg0)) { (ca, th, st, wp) => testFunc(ctx, func, Seq(arg0)) { (ctx, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) match { nameOf(ctx.curInst(st, 0)) match {
case "@osr_test_base_v1.entry.trap_base_exit" => { case "@osr_test_base_v1.entry.trap_base_exit" => {
val Seq(rv) = ca.dumpKeepalives(st, 0) val Seq(rv) = ctx.dumpKeepalives(st, 0)
ca.toInt(rv) shouldBe 6 ctx.handleToUInt(rv.asInstanceOf[MuIntValue]) shouldBe 6
TrapRebindPassVoid(st) returnFromTrap(st)
} }
} }
} }
ca.close() ctx.closeContext()
} }
"@sum" should "trigger trap when n >= 5 and work with OSR" in { "@sum" should "trigger trap when n >= 5 and work with OSR" in {
val ca = microVM.newClientAgent() val ctx = microVM.newContext()
val func = ca.putFunction("@osr_test_base") val func = ctx.handleFromFunc("@osr_test_base")
val arg0 = ca.putInt("@i64", 8) val arg0 = ctx.handleFromInt64(8)
testFunc(ca, func, Seq(arg0)) { (ca, th, st, wp) => testFunc(ctx, func, Seq(arg0)) { (ctx, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) match { nameOf(ctx.curInst(st, 0)) match {
case "@sum_v1.opt.trap_opt" => { case "@sum_v1.opt.trap_opt" => {
val Seq(n, i, s) = ca.dumpKeepalives(st, 0) val Seq(n, i, s) = ctx.dumpKeepalives(st, 0)
ca.toInt(s) shouldBe 10 ctx.handleToUInt(s.asInstanceOf[MuIntValue]) shouldBe 10
ca.toInt(i) shouldBe 5 ctx.handleToUInt(i.asInstanceOf[MuIntValue]) shouldBe 5
ca.toInt(n) shouldBe 8 ctx.handleToUInt(n.asInstanceOf[MuIntValue]) shouldBe 8
// Emulate optimising compiling by loading a pre-optimised version. // Emulate optimising compiling by loading a pre-optimised version.
val r = new FileReader("tests/uvm-refimpl-test/osr-tests-part2.uir") val r = new FileReader("tests/uvm-refimpl-test/osr-tests-part2.uir")
try { try {
ca.loadBundle(r) ctx.loadBundle(r)
} finally { } finally {
r.close() r.close()
} }
// OSR // OSR
ca.popFrame(st) ctx.popFrame(st)
val oneShotFunc = ca.putFunction("@sum_osr_oneshot") val oneShotFunc = ctx.handleFromFunc("@sum_osr_oneshot")
ca.pushFrame(st, oneShotFunc, Seq(s, i, n)) ctx.pushFrame(st, oneShotFunc)
// Continue // Continue
TrapRebindPassVoid(st) Rebind(st, PassValues(Seq(s, i, n)))
} }
case "@osr_test_base_v1.entry.trap_base_exit" => { case "@osr_test_base_v1.entry.trap_base_exit" => {
val Seq(rv) = ca.dumpKeepalives(st, 0) val Seq(rv) = ctx.dumpKeepalives(st, 0)
ca.toInt(rv) shouldBe 28 ctx.handleToUInt(rv.asInstanceOf[MuIntValue]) shouldBe 28
TrapRebindPassVoid(st) returnFromTrap(st)
} }
} }
} }
// The second time when it is called, it should call the second version // The second time when it is called, it should call the second version
// and OSR should be unnecessary. // and OSR should be unnecessary.
testFunc(ca, func, Seq(arg0)) { (ca, th, st, wp) => testFunc(ctx, func, Seq(arg0)) { (ctx, th, st, wp) =>
nameOf(ca.currentInstruction(st, 0)) match { nameOf(ctx.curInst(st, 0)) match {
case "@osr_test_base_v1.entry.trap_base_exit" => { case "@osr_test_base_v1.entry.trap_base_exit" => {
val Seq(rv) = ca.dumpKeepalives(st, 0) val Seq(rv) = ctx.dumpKeepalives(st, 0)
ca.toInt(rv) shouldBe 28 ctx.handleToUInt(rv.asInstanceOf[MuIntValue]) shouldBe 28
TrapRebindPassVoid(st) returnFromTrap(st)
} }
} }
} }
ca.close() ctx.closeContext()
} }
} }
\ No newline at end of file
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
RET %rv RET %rv
} }
.funcsig @sum_osr_oneshot_sig = @i64 (@i64 @i64 @i64) .funcsig @sum_osr_oneshot_sig = (@i64 @i64 @i64) -> (@i64)
// Calculate the remaining sum. // Calculate the remaining sum.
// Given s, i, n, the result is s + (n-i)*(n+i-1)/2 // Given s, i, n, the result is s + (n-i)*(n+i-1)/2
......
// requires "primitives.uir" // requires "primitives.uir"
.funcsig @v_i = @void (@i64) .funcsig @v_i = (@i64) -> ()
.funcdef @intro_test_base VERSION @intro_test_base_v1 <@v_i> { .funcdef @intro_test_base VERSION @intro_test_base_v1 <@v_i> {
%entry(<@i64> %n): %entry(<@i64> %n):
%rv = CALL <@v_i> @intro_rec (%n) %rv = [%call] CALL <@i_i> @intro_rec (%n)
COMMINST @uvm.thread_exit COMMINST @uvm.thread_exit
} }
.funcdef @intro_rec VERSION @intro_rec_v1 <@v_i> { .funcdef @intro_rec VERSION @intro_rec_v1 <@i_i> {
%entry(<@i64> %n): %entry(<@i64> %n):
%isz = EQ <@i64> %n @I64_0 %isz = EQ <@i64> %n @I64_0
BRANCH2 %isz %zero(%n) %nz(%n) BRANCH2 %isz %zero(%n) %nz(%n)
%zero(<@i64> %n): %zero(<@i64> %n):
%trap_rec = TRAP <@i64> KEEPALIVE(%n) %v = [%trap_rec] TRAP <@i64> KEEPALIVE(%n)
RET %trap_rec RET %v
%nz(<@i64> %n): %nz(<@i64> %n):
%nm1 = SUB <@i64> %n @I64_1 %nm1 = SUB <@i64> %n @I64_1
%rv = CALL <@v_i> @intro_rec (%nm1) KEEPALIVE(%n %nm1) %rv = [%call] CALL <@i_i> @intro_rec (%nm1) KEEPALIVE(%n %nm1)
RET %rv RET %rv
} }
.funcdef @osr_test_base VERSION @osr_test_base_v1 <@v_i> { .funcdef @osr_test_base VERSION @osr_test_base_v1 <@v_i> {
%entry(<@i64> %n): %entry(<@i64> %n):
%rv = CALL <@i_i> @sum (%n) %rv = [%call] CALL <@i_i> @sum (%n)
%trap_base_exit = TRAP <@void> KEEPALIVE (%rv) [%trap_base_exit] TRAP <> KEEPALIVE (%rv)
COMMINST @uvm.thread_exit COMMINST @uvm.thread_exit
} }
...@@ -56,6 +56,6 @@ ...@@ -56,6 +56,6 @@
RET %s RET %s
%opt(<@i64> %n <@i64> %i <@i64> %s): %opt(<@i64> %n <@i64> %i <@i64> %s):
%trap_opt = TRAP <@void> KEEPALIVE(%n %i %s) [%trap_opt] TRAP <> KEEPALIVE(%n %i %s)
THROW @NULLREF // unreachable THROW @NULLREF // unreachable
} }
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