Commit 6a609132 authored by Kunshan Wang's avatar Kunshan Wang

THREADLOCAL(xxx) parsing

parent e600d971
......@@ -199,7 +199,7 @@ instBody
| 'CCALL' callConv=flag '<' funcTy=type funcSig '>' callee=value argList excClause keepAliveClause # InstCCall
// Thread and Stack Operations
| 'NEWTHREAD' stack=value newStackClause excClause # InstNewThread
| 'NEWTHREAD' stack=value threadLocalClause? newStackClause excClause # InstNewThread
| 'SWAPSTACK' swappee=value curStackClause newStackClause excClause keepAliveClause # InstSwapStack
// Common Instructions
......@@ -234,6 +234,10 @@ excClause
keepAliveClause
: ('KEEPALIVE' '(' value* ')')?
;
threadLocalClause
: ('THREADLOCAL' '(' value ')')
;
flagList
: '[' flag* ']'
......
......@@ -393,6 +393,9 @@ private[textinput] class InstanceUIRTextReader(idFactory: IDFactory, source: Str
Some(ExcClause(ec.nor, ec.exc))
}
implicit def resThreadLocalClause(tlc: ThreadLocalClauseContext): Option[SSAVariable] =
Option(tlc).map { theTlc => resVar(theTlc.value()) }
implicit def resNewStackClause(nsc: NewStackClauseContext): NewStackAction = {
nsc match {
case a: NewStackPassValueContext => PassValues(a.typeList(), a.argList())
......@@ -553,8 +556,9 @@ private[textinput] class InstanceUIRTextReader(idFactory: IDFactory, source: Str
i.callee = ii.callee; i.argList = ii.argList; i.excClause = ii.excClause; i.keepAlives = ii.keepAliveClause
}
case ii: InstNewThreadContext =>
InstNewThread(null, null, null).later(phase4) { i =>
InstNewThread(null, null, null, null).later(phase4) { i =>
i.stack = ii.stack
i.threadLocal = ii.threadLocalClause
i.newStackAction = ii.newStackClause
i.excClause = ii.excClause
}
......
......@@ -506,7 +506,7 @@ class MuCtx(_mutator: Mutator)(
case HowToResume.PassValues(values) => ItprHowToResume.PassValues(values.map(_.vb))
case HowToResume.ThrowExc(exc) => ItprHowToResume.ThrowExc(exc.vb.objRef)
}
val thr = microVM.threadStackManager.newThread(sv, itprHtr)
val thr = microVM.threadStackManager.newThread(sv, 0L, itprHtr) // TODO: FIXME!!
val nb = BoxThread(Some(thr))
addHandle(MuThreadRefValue(InternalTypes.THREADREF, nb))
......
......@@ -518,7 +518,7 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
}
}
case i @ InstNewThread(stack, newStackAction, excClause) => {
case i @ InstNewThread(stack, threadLocal, newStackAction, excClause) => {
val newStack = stack.asStack.getOrElse {
throw new UvmRuntimeException(ctx + "Attempt to bind to a NULL stack.")
}
......@@ -526,11 +526,11 @@ trait InstructionExecutor extends InterpreterActions with CommInstExecutor {
val newThread = newStackAction match {
case PassValues(argTys, args) => {
val argBoxes = args.map(boxOf)
microVM.threadStackManager.newThread(newStack, HowToResume.PassValues(argBoxes))
microVM.threadStackManager.newThread(newStack, 0L, HowToResume.PassValues(argBoxes)) // TODO: FIXME
}
case ThrowExc(exc) => {
val excAddr = exc.asRef
microVM.threadStackManager.newThread(newStack, HowToResume.ThrowExc(excAddr))
microVM.threadStackManager.newThread(newStack, 0L, HowToResume.ThrowExc(excAddr)) // TODO: FIXME
}
}
results(0).asThread = Some(newThread)
......
......@@ -26,8 +26,14 @@ object HowToResume {
/**
* A thread that interprets Mu instruction.
* <p>
* @param id The thread ID
* @param initialStack The initial stack it binds to
* @param threadLocal The initial thread-local object reference
* @param mutator The Mutator object, for memory management
* @param htr How to resume. Either pass value or throw exception.
*/
class InterpreterThread(val id: Int, initialStack: InterpreterStack, val mutator: Mutator, htr: HowToResume)(
class InterpreterThread(val id: Int, initialStack: InterpreterStack, threadLocal: Long, htr: HowToResume, val mutator: Mutator)(
implicit protected val microVM: MicroVM) extends InstructionExecutor with HasID {
import InterpreterThread._
......@@ -65,6 +71,9 @@ trait InterpreterThreadState {
/** Object-pinnning multiset. */
val pinSet = new ArrayBuffer[Word]
/** Thread-local object reference. */
val threadLocal = BoxRef(0L)
protected def curStack = stack.get
protected def top: InterpreterFrame = curStack.top
......
......@@ -103,10 +103,10 @@ class ThreadStackManager(implicit microVM: MicroVM, nativeCallHelper: NativeCall
/**
* Create a new thread, bind to a given stack.
*/
def newThread(stack: InterpreterStack, htr: HowToResume): InterpreterThread = {
def newThread(stack: InterpreterStack, threadLocal: Long, htr: HowToResume): InterpreterThread = {
val mutator = microVM.memoryManager.makeMutator()
val id = threadRegistry.getID()
val thr = new InterpreterThread(id, stack, mutator, htr)
val thr = new InterpreterThread(id, stack, threadLocal, htr, mutator)
threadRegistry.put(thr)
thr
}
......
......@@ -252,7 +252,8 @@ case class InstCCall(var callConv: Flag, var funcTy: Type, var sig: FuncSig, var
var argList: Seq[SSAVariable], var excClause: Option[ExcClause], var keepAlives: Seq[LocalVariable])
extends CallLike with HasExcClause with HasKeepAliveClause with OSRPoint
case class InstNewThread(var stack: SSAVariable, var newStackAction: NewStackAction, var excClause: Option[ExcClause]) extends Instruction with HasExcClause
case class InstNewThread(var stack: SSAVariable, var threadLocal: Option[SSAVariable],
var newStackAction: NewStackAction, var excClause: Option[ExcClause]) extends Instruction with HasExcClause
case class InstSwapStack(var swappee: SSAVariable, var curStackAction: CurStackAction, var newStackAction: NewStackAction,
var excClause: Option[ExcClause], var keepAlives: Seq[LocalVariable]) extends HasExcClause with HasKeepAliveClause with OSRPoint {
......
......@@ -10,12 +10,12 @@ import uvm.comminsts._
trait ExtraMatchers extends Assertions with Matchers {
import ExtraMatchers._
import ExtraMatchers_._
implicit def anythingToAnythingExtraMatcher[U](thing: U) = new AnythingExtraMatchers(thing)
val thatsIt = { f: Any => }
case object nan
case class ExactFloat(num: Float)
case class ExactDouble(num: Double)
val NaN = ExtraMatchers_.NaN
def exactly(num: Float) = ExactFloat(num)
def exactly(num: Double) = ExactDouble(num)
......@@ -23,7 +23,15 @@ trait ExtraMatchers extends Assertions with Matchers {
def bitsd(num: Long) = java.lang.Double.longBitsToDouble(num)
}
object ExtraMatchers_ {
case object NaN
case class ExactFloat(num: Float)
case class ExactDouble(num: Double)
}
object ExtraMatchers extends ExtraMatchers {
import ExtraMatchers_._
implicit class AnythingExtraMatchers[U](val thing: U) extends AnyVal {
def shouldBeA[T: ClassTag](f: T => Unit): Unit = {
val ct = classTag[T]
......@@ -48,7 +56,7 @@ object ExtraMatchers extends ExtraMatchers {
thing shouldBeA[ConstFloat] { its =>
its.constTy shouldBeA[TypeFloat] thatsIt
something match {
case `nan` => assert(its.num.isNaN)
case NaN => its.num.isNaN shouldBe true
case ExactFloat(num) => its.num shouldEqual num
case num: Float => its.num shouldEqual (num +- 0.001F)
case _ => its.num shouldEqual something
......@@ -60,7 +68,7 @@ object ExtraMatchers extends ExtraMatchers {
thing shouldBeA[ConstDouble] { its =>
its.constTy shouldBeA[TypeDouble] thatsIt
something match {
case `nan` => assert(its.num.isNaN)
case NaN => its.num.isNaN shouldBe true
case ExactDouble(num) => its.num shouldEqual num
case num: Double => its.num shouldEqual (num +- 0.001F)
case _ => its.num shouldEqual something
......
......@@ -182,13 +182,13 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
our const "@cixovf2" shouldBeAConstIntOf (64, BigInt("8000000000000000", 16))
our const "@cf" shouldBeAConstFloatOf 3.14F
our const "@cfnan" shouldBeAConstFloatOf nan
our const "@cfnan" shouldBeAConstFloatOf NaN
our const "@cfninf" shouldBeAConstFloatOf Float.NegativeInfinity
our const "@cfpinf" shouldBeAConstFloatOf Float.PositiveInfinity
our const "@cfbits" shouldBeAConstFloatOf exactly(bitsf(0x12345678))
our const "@cd" shouldBeAConstDoubleOf 6.28D
our const "@cdnan" shouldBeAConstDoubleOf nan
our const "@cdnan" shouldBeAConstDoubleOf NaN
our const "@cdninf" shouldBeAConstDoubleOf Double.NegativeInfinity
our const "@cdpinf" shouldBeAConstDoubleOf Double.PositiveInfinity
our const "@cdbits" shouldBeAConstDoubleOf exactly(bitsd(0xfedcba9876543210L))
......@@ -1216,17 +1216,26 @@ trait TestingBundlesValidators extends Matchers with ExtraMatchers {
my inst "%nt1" shouldBeA[InstNewThread] { its =>
its.stack shouldBe (my value "%s1")
its.threadLocal shouldBe None
its.newStackAction shouldBe PassValues(qw"@i64 @i64".map(our.ty), qw"@I64_0 @I64_1".map(our.value))
its.excClause shouldBe None
}
my inst "%nt2" shouldBeA[InstNewThread] { its =>
its.stack shouldBe (my value "%s2")
its.threadLocal shouldBe None
its.newStackAction shouldBe ThrowExc(our value "@NULLREF")
its.excClause shouldBe Some(ExcClause(
DestClause(the bb "%nor", Seq()),
DestClause(the bb "%exc", Seq())
))
}
my inst "%nt3" shouldBeA[InstNewThread] { its =>
its.stack shouldBe (my value "%s1")
its.threadLocal.isDefined shouldBe true
its.threadLocal.get shouldBe (my value "%tl")
its.newStackAction shouldBe PassValues(qw"@i64 @i64".map(our.ty), qw"@I64_0 @I64_1".map(our.value))
its.excClause shouldBe None
}
}
}
......
......@@ -461,6 +461,10 @@
%s2 = COMMINST @uvm.new_stack <[@iii_sig]> (@callee2)
%t2 = [%nt2] NEWTHREAD %s2 THROW_EXC @NULLREF EXC(%nor() %exc())
%s3 = COMMINST @uvm.new_stack <[@iii_sig]> (@callee2)
%tl = NEW<@i64>
%t3 = [%nt3] NEWTHREAD %s1 THREADLOCAL(%tl) PASS_VALUES <@i64 @i64> (@I64_0 @I64_1)
%nor():
RET ()
......
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