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

SimpleImmixMutator.scala 2.39 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
class SimpleImmixMutator(val heap: SimpleImmixHeap, val space: SimpleImmixSpace, val los: LargeObjectSpace, name: String)(
16
  implicit memorySupport: MemorySupport)
17
    extends Mutator(name) with Allocator {
Kunshan Wang's avatar
Kunshan Wang committed
18
19
20

  import SimpleImmixMutator._

21
22
  logger.debug("Creating mutator %s...".format(name))

Kunshan Wang's avatar
Kunshan Wang committed
23
24
25
26
27
28
29
30
31
32
  private var curBlockAddr: Option[Word] = None

  private var cursor: Word = _

  private var limit: Word = _

  getNewBlock()

  private def getNewBlock(): Unit = {
    val newAddr = tryRepeatedly {
33
34
35
      val toReturn = curBlockAddr
      curBlockAddr = None
      space.tryGetBlock(toReturn, this).orElse {
Kunshan Wang's avatar
Kunshan Wang committed
36
        heap.mutatorTriggerAndWaitForGCEnd(true)
37
        logger.debug("Try again to get block...")
Kunshan Wang's avatar
Kunshan Wang committed
38
39
40
41
42
43
        None
      }
    }
    curBlockAddr = Some(newAddr)
    cursor = newAddr
    limit = newAddr + SimpleImmixSpace.BLOCK_SIZE
44
    logger.debug("Got block. cursor=0x%x limit=0x%x".format(cursor, limit))
Kunshan Wang's avatar
Kunshan Wang committed
45
46
47
48
49
  }

  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
50
    val result = tryRepeatedly { // Actually try at most twice.
Kunshan Wang's avatar
Kunshan Wang committed
51
52
53
54
55
      //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) {
56
        if (userEnd - gcStart > SimpleImmixSpace.SOS_THRESHOLD) {
Kunshan Wang's avatar
Kunshan Wang committed
57
58
59
60
61
62
63
64
65
66
67
68
          Some(los.alloc(size, align, headerSize))
        } else {
          logger.debug("Getting new block...")
          getNewBlock
          logger.debug("got new block.")
          None
        }
      } else {
        cursor = userEnd
        Some(userStart)
      }
    }
69
70
    logger.debug("alloc(%d, %d, %d) = %d 0x%x".format(size, align, headerSize, result, result))
    result
Kunshan Wang's avatar
Kunshan Wang committed
71
72
73
  }

  def close() {
74
75
    logger.debug("Closing mutator %s...".format(name))
    curBlockAddr.foreach(a => space.returnBlock(a, this))
Kunshan Wang's avatar
Kunshan Wang committed
76
77
  }
}