To protect your data, the CISO officer has suggested users to enable GitLab 2FA as soon as possible.

TypeSizes.scala 4.88 KB
Newer Older
1
2
3
4
package uvm.refimpl.mem

import uvm.types._
import uvm.refimpl.UvmRefImplException
5
import uvm.refimpl.nat.PlatformConstants
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

/**
 * Responsible for object layout.
 * <p>
 * Scalar object:
 *
 * <pre>
 *     8 bytes
 * +----------------+----------------
 * | tag            | payload...
 * +----------------+----------------
 * ^objref-8bytes   ^ objref
 * </pre>
 *
 * Hybrid:
 *
 * <pre>
 *    8 bytes           8 bytes
 * +-----------------+-----------------+------------+--------------
 * | var part length | tag             | fixed part | var part
 * +-----------------+-----------------+------------+--------------
 * ^objref-16bytes   ^objref-8bytes    ^ objref
 * </pre>
 *
 * tag: (not forwarded)
 *
 * <pre>
 *   1bit         1bit       30bit            32bit
 * +-----------+--------+------------------+---------+
 * | moved = 0 | marked | (unused bits...) | type id |
 * +-----------+--------+------------------+---------+
 * 64          63       62                 32        0
 * </pre>
 * (forwarded)
 * <pre>
 *   1bit            15bit               48bits
 * +-----------+------------------+------------------+
 * | moved = 1 | (unused bits...) | destination addr |
 * +-----------+------------------+------------------+
 * 64          63                 48                 0
 * </pre>
 */
object TypeSizes {
49
  type Word = PlatformConstants.Word
50

51
52
53
  val WORD_SIZE_LOG: Word = PlatformConstants.WORD_SIZE_LOG
  val WORD_SIZE_BITS: Word = PlatformConstants.WORD_SIZE_BITS
  val WORD_SIZE_BYTES: Word = PlatformConstants.WORD_SIZE_BYTES
54
55
56
57
58
59
60

  val GC_HEADER_SIZE_SCALAR: Word = 8L;
  val GC_HEADER_SIZE_HYBRID: Word = 16L;

  val GC_HEADER_OFFSET_TAG: Word = -8L;
  val GC_HEADER_OFFSET_HYBRID_LENGTH: Word = -16L;

61
62
63
64
  val MARK_MASK = 0x4000000000000000L

  val MOVE_MASK = 0x8000000000000000L

65
  def sizeOf(ty: Type): Word = ty match {
Kunshan Wang's avatar
Kunshan Wang committed
66
67
68
69
70
71
    case TypeInt(l)            => intBitsToBytes(l)
    case _: TypeFloat          => 4L
    case _: TypeDouble         => 8L
    case _: TypeRef            => WORD_SIZE_BYTES
    case _: TypeIRef           => 2L * WORD_SIZE_BYTES
    case _: TypeWeakRef        => WORD_SIZE_BYTES
72
    case t @ TypeStruct(ftys)  => structPrefixSizeOf(t, ftys.size)
Kunshan Wang's avatar
Kunshan Wang committed
73
74
75
    case t @ TypeArray(et, l)  => seqPrefixSizeOf(t, l)
    case _: TypeHybrid         => throw new IllegalArgumentException("Hybrid should use hybridSizeOf to probe size")
    case _: TypeVoid           => 0L
76
77
78
    case _: TypeFuncRef        => WORD_SIZE_BYTES
    case _: TypeThreadRef      => WORD_SIZE_BYTES
    case _: TypeStackRef       => WORD_SIZE_BYTES
Kunshan Wang's avatar
Kunshan Wang committed
79
80
    case _: TypeTagRef64       => 8L
    case t @ TypeVector(et, l) => seqPrefixSizeOf(t, l)
81
82
    case _: TypeUPtr           => WORD_SIZE_BYTES
    case _: TypeUFuncPtr       => WORD_SIZE_BYTES
83
84
85
86
  }

  def alignOf(ty: Type): Word = ty match {
    case TypeStruct(ftys) => ftys.map(sizeOf).max
Kunshan Wang's avatar
Kunshan Wang committed
87
88
89
90
    case TypeArray(et, _) => alignOf(et)
    case _: TypeHybrid    => throw new IllegalArgumentException("Hybrid should use hybridAlignOf to probe alignment")
    case _: TypeVoid      => 1L
    case _                => sizeOf(ty)
91
92
93
  }

  def hybridSizeOf(ty: TypeHybrid, len: Word): Word = {
Kunshan Wang's avatar
Kunshan Wang committed
94
    val fixedSize = structPrefixSizeOf(ty, ty.fieldTys.size)
95
96
97
98
99
100
101
    val varAlign = alignOf(ty.varTy)
    val varSize = shiftOffsetOf(ty.varTy, len)
    val size = alignUp(fixedSize, varAlign) + varSize
    return size
  }

  def hybridAlignOf(ty: TypeHybrid, len: Word): Word = {
Kunshan Wang's avatar
Kunshan Wang committed
102
    val fieldAligns = ty.fieldTys.map(alignOf)
103
    val varAlign = alignOf(ty.varTy)
Kunshan Wang's avatar
Kunshan Wang committed
104
    val align = fieldAligns.foldLeft(varAlign)(Math.max)
105
106
107
    return align
  }

Kunshan Wang's avatar
Kunshan Wang committed
108
  def fieldOffsetOf(ty: AbstractStructType, index: Int): Word = {
109
    val fieldType = ty.fieldTys(index)
110
    val fieldAlign = alignOf(fieldType)
111
    val prefixSize = structPrefixSizeOf(ty, index)
112
113
114
    val offset = alignUp(prefixSize, fieldAlign)
    return offset
  }
Kunshan Wang's avatar
Kunshan Wang committed
115

116
117
118
119
120
121
122
  def elemOffsetOf(ty: AbstractSeqType, length: Word): Word = {
    return seqPrefixSizeOf(ty, length)
  }

  def shiftOffsetOf(ty: Type, index: Word): Word = {
    return alignUp(sizeOf(ty), alignOf(ty)) * index
  }
Kunshan Wang's avatar
Kunshan Wang committed
123

124
  def varPartOffsetOf(ty: TypeHybrid): Word = {
Kunshan Wang's avatar
Kunshan Wang committed
125
    return alignUp(structPrefixSizeOf(ty, ty.fieldTys.length), alignOf(ty.varTy))
126
  }
127

Kunshan Wang's avatar
Kunshan Wang committed
128
  def structPrefixSizeOf(ty: AbstractStructType, prefixLen: Int): Word = {
129
    val sz = ty.fieldTys.take(prefixLen).foldLeft(0L) { (oldSz, nextTy) =>
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
      alignUp(oldSz, alignOf(nextTy)) + sizeOf(nextTy)
    }
    return sz
  }

  def seqPrefixSizeOf(ty: AbstractSeqType, length: Word): Word = {
    return shiftOffsetOf(ty.elemTy, length)
  }

  def nextPowOfTwo(n: Word): Word = {
    var i = 1L
    while (i < n) {
      i <<= 1L
    }
    return i
  }

  def intBitsToBytes(n: Word): Word = {
    val p2 = nextPowOfTwo(n)
    if (p2 < 8L) {
      return 1L;
    } else {
      return p2 / 8L;
    }
  }

  def alignUp(n: Word, alignment: Word): Word = {
    return ((n - 1) & ~(alignment - 1)) + alignment;
  }

  def alignDown(n: Word, alignment: Word): Word = {
    return n & ~(alignment - 1);
  }
}