-
Notifications
You must be signed in to change notification settings - Fork 360
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use Array[Int]
instead of Array[Array[Boolean]]
for [class,trait]_has_trait
#3279
Changes from 5 commits
fb93eb3
d55264e
7850cfe
d2aff25
34979a7
dc28a54
51853bf
93716f8
4bedc6d
5ff3320
852bea5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package scala.scalanative | ||
|
||
private[scalanative] class BitMatrix private ( | ||
bits: Array[Long], | ||
columns: Int | ||
) { | ||
import BitMatrix.{AddressBitsPerWord, ElementSize, RightBits} | ||
|
||
def set(row: Int, col: Int): Unit = { | ||
val bitIndex = row * columns + col | ||
bits(bitIndex >> AddressBitsPerWord) |= 1L << (bitIndex & RightBits) | ||
} | ||
|
||
def toSeq = bits.toSeq | ||
} | ||
private[scalanative] object BitMatrix { | ||
private[scalanative] final val AddressBitsPerWord = 6 // Int Based 2^6 = 64 | ||
private[scalanative] final val ElementSize = 1 << AddressBitsPerWord | ||
private[scalanative] final val RightBits = ElementSize - 1 | ||
|
||
def apply(rows: Int, columns: Int): BitMatrix = { | ||
val nbits = rows * columns | ||
val length = (nbits + RightBits) >> AddressBitsPerWord | ||
new BitMatrix(new Array[Long](length), columns) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -66,27 +66,142 @@ object Generate { | |
} | ||
|
||
def genClassHasTrait(): Unit = { | ||
genHasTrait( | ||
ClassHasTraitName, | ||
ClassHasTraitSig, | ||
meta.hasTraitTables.classHasTraitTy, | ||
meta.hasTraitTables.classHasTraitVal | ||
) | ||
} | ||
|
||
def genTraitHasTrait(): Unit = { | ||
genHasTrait( | ||
TraitHasTraitName, | ||
TraitHasTraitSig, | ||
meta.hasTraitTables.traitHasTraitTy, | ||
meta.hasTraitTables.traitHasTraitVal | ||
) | ||
} | ||
|
||
// def __get_[class,trait]_has_trait(firstid: Int, secondid: Int): Boolean = { | ||
// val columns = meta.traits.length | ||
// val row = firstid * columns | ||
// val bitIndex = row + secondid | ||
// val arrayPos = bitIndex >> AddressBitsPerWord | ||
// val long = bits(arrayPos) | ||
// val toShift = bitIndex & RightBits | ||
// val toShiftLong = toShift.toLong | ||
// val mask = 1L << toShiftLong | ||
// val and = long & mask | ||
// val result = and != 0L | ||
// | ||
// result | ||
// } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if we need this comment. I can remove it if you think it's redundant. |
||
private def genHasTrait( | ||
name: Global.Member, | ||
sig: Type.Function, | ||
tableTy: Type, | ||
tableVal: Val | ||
): Unit = { | ||
implicit val fresh = Fresh() | ||
val classid, traitid = Val.Local(fresh(), Type.Int) | ||
val boolptr = Val.Local(fresh(), Type.Ptr) | ||
val firstid, secondid = Val.Local(fresh(), Type.Int) | ||
val row = Val.Local(fresh(), Type.Int) | ||
val columns = Val.Int(meta.traits.length) | ||
val bitIndex = Val.Local(fresh(), Type.Int) | ||
val arrayPos = Val.Local(fresh(), Type.Int) | ||
val longptr = Val.Local(fresh(), Type.Ptr) | ||
val long = Val.Local(fresh(), Type.Long) | ||
val toShift = Val.Local(fresh(), Type.Int) | ||
val toShiftLong = Val.Local(fresh(), Type.Long) | ||
val mask = Val.Local(fresh(), Type.Long) | ||
val and = Val.Local(fresh(), Type.Long) | ||
val result = Val.Local(fresh(), Type.Bool) | ||
|
||
buf += Defn.Define( | ||
Attrs(inlineHint = Attr.AlwaysInline), | ||
ClassHasTraitName, | ||
ClassHasTraitSig, | ||
name, | ||
sig, | ||
Seq( | ||
Inst.Label(fresh(), Seq(classid, traitid)), | ||
Inst.Label(fresh(), Seq(firstid, secondid)), | ||
Inst.Let( | ||
row.name, | ||
Op.Bin(Bin.Imul, Type.Int, firstid, columns), | ||
Next.None | ||
), | ||
Inst.Let( | ||
boolptr.name, | ||
bitIndex.name, | ||
Op.Bin(Bin.Iadd, Type.Int, row, secondid), | ||
Next.None | ||
), | ||
Inst.Let( | ||
arrayPos.name, | ||
Op.Bin( | ||
Bin.Ashr, | ||
Type.Int, | ||
bitIndex, | ||
Val.Int(BitMatrix.AddressBitsPerWord) | ||
), | ||
Next.None | ||
), | ||
Inst.Let( | ||
longptr.name, | ||
Op.Elem( | ||
meta.hasTraitTables.classHasTraitTy, | ||
meta.hasTraitTables.classHasTraitVal, | ||
Seq(Val.Int(0), classid, traitid) | ||
tableTy, | ||
tableVal, | ||
Seq(Val.Int(0), arrayPos) | ||
), | ||
Next.None | ||
), | ||
Inst.Let(long.name, Op.Load(Type.Long, longptr), Next.None), | ||
Inst.Let( | ||
toShift.name, | ||
Op.Bin( | ||
Bin.And, | ||
Type.Int, | ||
bitIndex, | ||
Val.Int(BitMatrix.RightBits) | ||
), | ||
Next.None | ||
), | ||
Inst.Let( | ||
toShiftLong.name, | ||
Op.Conv( | ||
Conv.Sext, | ||
Type.Long, | ||
toShift | ||
), | ||
Next.None | ||
), | ||
Inst.Let( | ||
mask.name, | ||
Op.Bin( | ||
Bin.Shl, | ||
Type.Long, | ||
Val.Long(1), | ||
toShiftLong | ||
), | ||
Next.None | ||
), | ||
Inst.Let( | ||
and.name, | ||
Op.Bin( | ||
Bin.And, | ||
Type.Long, | ||
long, | ||
mask | ||
), | ||
Next.None | ||
), | ||
Inst.Let( | ||
result.name, | ||
Op.Comp( | ||
Comp.Ine, | ||
Type.Long, | ||
and, | ||
Val.Long(0) | ||
), | ||
Next.None | ||
), | ||
Inst.Let(result.name, Op.Load(Type.Bool, boolptr), Next.None), | ||
Inst.Ret(result) | ||
) | ||
) | ||
|
@@ -100,33 +215,6 @@ object Generate { | |
} | ||
} | ||
|
||
def genTraitHasTrait(): Unit = { | ||
implicit val fresh = Fresh() | ||
val leftid, rightid = Val.Local(fresh(), Type.Int) | ||
val boolptr = Val.Local(fresh(), Type.Ptr) | ||
val result = Val.Local(fresh(), Type.Bool) | ||
|
||
buf += Defn.Define( | ||
Attrs(inlineHint = Attr.AlwaysInline), | ||
TraitHasTraitName, | ||
TraitHasTraitSig, | ||
Seq( | ||
Inst.Label(fresh(), Seq(leftid, rightid)), | ||
Inst.Let( | ||
boolptr.name, | ||
Op.Elem( | ||
meta.hasTraitTables.traitHasTraitTy, | ||
meta.hasTraitTables.traitHasTraitVal, | ||
Seq(Val.Int(0), leftid, rightid) | ||
), | ||
Next.None | ||
), | ||
Inst.Let(result.name, Op.Load(Type.Bool, boolptr), Next.None), | ||
Inst.Ret(result) | ||
) | ||
) | ||
} | ||
|
||
/* Generate set of instructions using common exception handling, generate method | ||
* would return 0 if would execute successfully exception and 1 in otherwise */ | ||
private def withExceptionHandler( | ||
|
@@ -504,7 +592,7 @@ object Generate { | |
} | ||
} | ||
|
||
private object Impl { | ||
object Impl { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I need to move the constats that I need in to use in |
||
val rttiModule = Global.Top("java.lang.rtti$") | ||
|
||
val ClassHasTraitName = | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a minimal version of our java BitSet implementation with fixed size and no bound checks.
It represents a matrix so it calculates the array index storing the matrix by rows.