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

SimpleImmixMutator.scala 2.17 KB
Newer Older
Kunshan Wang's avatar
Kunshan Wang committed
1
2
3
4
5
6
7
8
package uvm.refimpl.mem.simpleimmix

import uvm.refimpl.mem._
import uvm.refimpl.mem.los.LargeObjectSpace
import org.slf4j.LoggerFactory
import com.typesafe.scalalogging.Logger
import TypeSizes.Word
import scala.annotation.tailrec
Kunshan Wang's avatar
Kunshan Wang committed
9
import uvm.utils.RetryUtils._
Kunshan Wang's avatar
Kunshan Wang committed
10
11
12
13
14

object SimpleImmixMutator {
  val logger = Logger(LoggerFactory.getLogger(getClass.getName))
}

15
16
17
class SimpleImmixMutator(val heap: SimpleImmixHeap, val space: SimpleImmixSpace, val los: LargeObjectSpace)(
  implicit memorySupport: MemorySupport)
    extends Mutator with Allocator {
Kunshan Wang's avatar
Kunshan Wang committed
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

  import SimpleImmixMutator._

  private var curBlockAddr: Option[Word] = None

  private var cursor: Word = _

  private var limit: Word = _

  getNewBlock()

  private def getNewBlock(): Unit = {
    val newAddr = tryRepeatedly {
      space.tryGetBlock(curBlockAddr).orElse {
        heap.mutatorTriggerAndWaitForGCEnd(true)
        None
      }
    }
    curBlockAddr = Some(newAddr)
    cursor = newAddr
    limit = newAddr + SimpleImmixSpace.BLOCK_SIZE
39
    logger.debug("Got block. cursor=0x%x limit=0x%x".format(cursor, limit))
Kunshan Wang's avatar
Kunshan Wang committed
40
41
42
43
44
  }

  override def alloc(size: Word, align: Word, headerSize: Word): Word = {
    logger.debug(s"alloc(${size}, ${align}, ${headerSize})")
    val actualAlign = if (align < TypeSizes.WORD_SIZE_BYTES) TypeSizes.WORD_SIZE_BYTES else align
45
    val result = tryRepeatedly { // Actually try at most twice.
Kunshan Wang's avatar
Kunshan Wang committed
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
      //If the first time failed, the second time cannot continue until a block is obtained. 
      val gcStart = TypeSizes.alignUp(cursor, align)
      val userStart = TypeSizes.alignUp(gcStart + headerSize, align)
      val userEnd = userStart + size
      if (userEnd >= limit) {
        if (userEnd - gcStart > SimpleImmixSpace.BLOCK_SIZE) {
          Some(los.alloc(size, align, headerSize))
        } else {
          logger.debug("Getting new block...")
          getNewBlock
          logger.debug("got new block.")
          None
        }
      } else {
        cursor = userEnd
        Some(userStart)
      }
    }
64
65
    logger.debug("alloc(%d, %d, %d) = %d 0x%x".format(size, align, headerSize, result, result))
    result
Kunshan Wang's avatar
Kunshan Wang committed
66
67
68
  }

  def close() {
Kunshan Wang's avatar
Kunshan Wang committed
69
    logger.debug("Closing mutator...")
Kunshan Wang's avatar
Kunshan Wang committed
70
71
72
    curBlockAddr.foreach(space.returnBlock)
  }
}