WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

MemoryDataScanner.scala 4.38 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
package uvm.refimpl.mem.scanning

import uvm.refimpl._
import uvm.refimpl.itpr._
import uvm.refimpl.mem._
import uvm.types._
import com.typesafe.scalalogging.StrictLogging
import TypeSizes._
import com.typesafe.scalalogging.Logger
import org.slf4j.LoggerFactory

object MemoryDataScanner extends StrictLogging {

  val paranoiaLogger = Logger(LoggerFactory.getLogger(getClass.getName() + ".paranoia"))

Kunshan Wang's avatar
Kunshan Wang committed
16 17 18 19
  /**
   * Scan an allocation unit. In this implementation, heap objects, alloca cells and global
   * cells all have the same layout.
   */
20
  def scanAllocUnit(objRef: Word, iRef: Word, handler: RefFieldHandler)(implicit microVM: MicroVM, memorySupport: MemorySupport) {
21
    val tag = HeaderUtils.getTag(objRef)
22
    logger.debug("Obj 0x%x, tag 0x%x".format(objRef, tag))
23
    val ty = HeaderUtils.getType(microVM, tag)
Kunshan Wang's avatar
Kunshan Wang committed
24
    logger.debug("Type: %s".format(ty.repr))
25
    scanField(ty, objRef, objRef, handler)
26 27
  }

28
  def scanField(ty: Type, objRef: Word, iRef: Word, handler: RefFieldHandler)(implicit microVM: MicroVM, memorySupport: MemorySupport) {
29 30
    ty match {
      case t: TypeRef => {
31
        val toObj = memorySupport.loadLong(iRef)
32
        logger.debug(s"Ref field ${iRef} -> ${toObj}")
Kunshan Wang's avatar
Kunshan Wang committed
33
        handler.memToHeap(objRef, iRef, toObj, false, false)
34 35
      }
      case t: TypeIRef => {
36
        val toObj = memorySupport.loadLong(iRef)
37
        logger.debug(s"IRef field ${iRef} -> ${toObj}")
Kunshan Wang's avatar
Kunshan Wang committed
38
        handler.memToHeap(objRef, iRef, toObj, false, false)
39 40
      }
      case t: TypeWeakRef => {
41
        val toObj = memorySupport.loadLong(iRef)
42
        logger.debug(s"WeakRef field ${iRef} -> ${toObj}")
Kunshan Wang's avatar
Kunshan Wang committed
43
        handler.memToHeap(objRef, iRef, toObj, true, false)
44 45
      }
      case t: TypeTagRef64 => {
46
        val bits = memorySupport.loadLong(iRef)
47 48 49 50 51 52 53 54 55 56 57 58 59
        if (paranoiaLogger.underlying.isDebugEnabled()) {
          paranoiaLogger.debug(s"Tagref bits ${bits}")
          if (OpHelper.tr64IsFp(bits)) {
            paranoiaLogger.debug(s"Tagref is FP: ${OpHelper.tr64ToFp(bits)}")
          } else if (OpHelper.tr64IsInt(bits)) {
            paranoiaLogger.debug(s"Tagref is Int: ${OpHelper.tr64ToInt(bits)}")
          } else if (OpHelper.tr64IsRef(bits)) {
            paranoiaLogger.debug(s"Tagref is Ref: ${OpHelper.tr64ToRef(bits)} tag: ${OpHelper.tr64ToTag(bits)}")
          }
        }
        if (OpHelper.tr64IsRef(bits)) {
          val toObj = OpHelper.tr64ToRef(bits)
          logger.debug(s"TagRef64 field ${iRef} -> ${toObj} tag: ${OpHelper.tr64ToTag(bits)}")
Kunshan Wang's avatar
Kunshan Wang committed
60
          handler.memToHeap(objRef, iRef, toObj, false, true)
61 62 63 64
        }
      }
      case t: TypeStruct => {
        var fieldAddr = iRef
65
        for (fieldTy <- t.fieldTys) {
66 67
          val fieldAlign = TypeSizes.alignOf(fieldTy)
          fieldAddr = TypeSizes.alignUp(fieldAddr, fieldAlign)
68
          scanField(fieldTy, objRef, fieldAddr, handler)
69 70 71 72 73 74 75 76 77
          fieldAddr += TypeSizes.sizeOf(fieldTy)
        }
      }
      case t: TypeArray => {
        val elemTy = t.elemTy
        val elemSize = TypeSizes.sizeOf(elemTy)
        val elemAlign = TypeSizes.alignOf(elemTy)
        var elemAddr = iRef
        for (i <- 0L until t.len) {
78
          scanField(elemTy, objRef, elemAddr, handler)
79 80 81 82 83 84 85 86 87 88 89 90 91
          elemAddr = TypeSizes.alignUp(elemAddr + elemSize, elemAlign)
        }

      }
      case t: TypeHybrid => {
        val fixedTy = t.fixedTy
        val varTy = t.varTy
        val fixedSize = TypeSizes.sizeOf(fixedTy)
        val fixedAlign = TypeSizes.alignOf(fixedTy)
        val varSize = TypeSizes.sizeOf(varTy)
        val varAlign = TypeSizes.alignOf(varTy)
        var curAddr = iRef
        val varLength = HeaderUtils.getVarLength(iRef)
92
        scanField(fixedTy, objRef, curAddr, handler)
93 94
        curAddr = TypeSizes.alignUp(curAddr + fixedSize, fixedAlign)
        for (i <- 0L until varLength) {
95
          scanField(varTy, objRef, curAddr, handler)
96 97 98
          curAddr = TypeSizes.alignUp(curAddr + varSize, varAlign)
        }
      }
99
      case t: TypeStackRef => {
100
        val toStackID = memorySupport.loadLong(iRef)
Kunshan Wang's avatar
Kunshan Wang committed
101 102 103 104 105 106 107 108 109 110
        val maybeToStack = if (toStackID == 0) {
          None
        } else {
          val toStack = microVM.threadStackManager.getStackByID(toStackID.toInt).getOrElse {
            throw new UvmRefImplException("Memory location 0x%x referring to non-existing stack %d".format(iRef, toStackID))
          }
          Some(toStack)
        }
        handler.memToStack(objRef, iRef, maybeToStack)
      }
Kunshan Wang's avatar
Kunshan Wang committed
111
      case _ => // Ignore non-reference fields.
112 113 114
    }
  }
}