GitLab will be upgraded on June 2nd 2020 at 2.00 pm (AEDT) to 3.00 pm (AEDT) due to Critical Security Patch Availability. During the update, GitLab and Mattermost services will not be available. If you have any concerns with this, please talk to local Gitlab admin team.

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