1 /*
2  * sys-emu - A system emulator for tutorials
3  * Copyright (C) 2018 - 2019 osdevelopment-info
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Affero General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Affero General Public License for more details.
14  *
15  * You should have received a copy of the GNU Affero General Public License
16  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17  */
18 package info.osdevelopment.sysemu.memory
19 
20 import info.osdevelopment.sysemu.support.Utilities._
21 import scala.util.{Failure, Success, Try}
22 
23 /**
24   * The object CombinedReadWriteMemory used to create instances of the memory. The maximum memory that can be handled is
25   * 1 EiB.
26   */
27 object CombinedReadWriteMemory {
28 
29   /**
30     * Creates a read-write memory with the given `size`.
31     * @param size the size of the memory
32     * @return a `Success` with the read-write memory with the given size or a `Failure`
33     */
34   def apply(size: Long): Try[CombinedReadWriteMemory] = {
35     if (size <= 0 | size > 1.Ei) Failure(new IllegalArgumentException("Max size supported is 1 EiB"))
36     else Try(new CombinedReadWriteMemory(size))
37   }
38 
39 }
40 
41 /**
42   * A read-write memory that can hold up to 2^60^ Bytes (1 EiB). Please note that the size is immediately allocated.
43   * @param size the size of the read-write memory to create
44   */
45 class CombinedReadWriteMemory private(val size: Long) extends ReadWriteMemory {
46 
47   /** The size of the last "memory module". */
48   private val remaining = size % 1.Gi
49   /** The number of modules needed to create the memory. */
50   private val numberModules = (if (remaining == 0) size / 1.Gi else size / 1.Gi + 1).asInstanceOf[Int]
51   /** The modules for the memory. */
52   private val modules = Array
53     .fill(numberModules){ SimpleReadWriteMemory(1.Gi.asInstanceOf[Int]) }
54     .collect{ case Success(m) => m}
55   if (modules.length != numberModules) {
56     throw new IllegalStateException("Cannot create ReadWriteMemory")
57   }
58 
59   /**
60     * The read method to read the value from the array of arrays.
61     * @param address the address to read
62     * @return a `Success` with the byte read at the given address or a `Failure`
63     */
64   protected override def doRead(address: Long): Try[Byte] = {
65     val module = address / 1.Gi
66     val offset = address % 1.Gi
67     modules(module.asInstanceOf[Int]).readByte(offset)
68   }
69 
70   /**
71     * The write method to write the value to the array.
72     * @param address the address to write
73     * @param value the `value` to write
74     * @return a `Success` if the write was successful, `Failure` otherwise
75     */
76   protected override def doWrite(address: Long, value: Byte): Try[Unit] = {
77     val module = address / 1.Gi
78     val offset = address % 1.Gi
79     modules(module.asInstanceOf[Int]).writeByte(offset.asInstanceOf[Int], value)
80   }
81 
82 }
Line Stmt Id Pos Tree Symbol Code
35 50 1361 - 1372 Apply scala.Long.> size.>(info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Ei)
35 53 1374 - 1442 Apply scala.util.Failure.apply scala.util.Failure.apply[Nothing](new scala.`package`.IllegalArgumentException("Max size supported is 1 EiB"))
35 47 1357 - 1358 Literal <nosymbol> 0
35 49 1368 - 1372 Select info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong.Ei info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Ei
35 52 1382 - 1441 Apply java.lang.IllegalArgumentException.<init> new scala.`package`.IllegalArgumentException("Max size supported is 1 EiB")
35 54 1374 - 1442 Block scala.util.Failure.apply scala.util.Failure.apply[Nothing](new scala.`package`.IllegalArgumentException("Max size supported is 1 EiB"))
35 48 1368 - 1369 Literal <nosymbol> 1L
35 51 1349 - 1372 Apply scala.Boolean.| size.<=(0).|(size.>(info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Ei))
36 56 1452 - 1490 Apply scala.util.Try.apply scala.util.Try.apply[info.osdevelopment.sysemu.memory.CombinedReadWriteMemory](new CombinedReadWriteMemory(size))
36 55 1456 - 1489 Apply info.osdevelopment.sysemu.memory.CombinedReadWriteMemory.<init> new CombinedReadWriteMemory(size)
36 57 1452 - 1490 Block scala.util.Try.apply scala.util.Try.apply[info.osdevelopment.sysemu.memory.CombinedReadWriteMemory](new CombinedReadWriteMemory(size))
48 59 1846 - 1850 Select info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong.Gi info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi
48 58 1846 - 1847 Literal <nosymbol> 1L
48 60 1839 - 1850 Apply scala.Long.% CombinedReadWriteMemory.this.size.%(info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi)
50 68 1942 - 2013 TypeApply scala.Any.asInstanceOf if (CombinedReadWriteMemory.this.remaining.==(0)) CombinedReadWriteMemory.this.size./(info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi) else CombinedReadWriteMemory.this.size./(info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi).+(1).asInstanceOf[Int]
50 62 1969 - 1970 Literal <nosymbol> 1L
50 65 1962 - 1973 Block scala.Long./ CombinedReadWriteMemory.this.size./(info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi)
50 64 1962 - 1973 Apply scala.Long./ CombinedReadWriteMemory.this.size./(info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi)
50 67 1979 - 1994 Block scala.Long.+ CombinedReadWriteMemory.this.size./(info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi).+(1)
50 61 1946 - 1960 Apply scala.Long.== CombinedReadWriteMemory.this.remaining.==(0)
50 63 1969 - 1973 Select info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong.Gi info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi
50 66 1979 - 1994 Apply scala.Long.+ CombinedReadWriteMemory.this.size./(info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi).+(1)
53 71 2129 - 2151 Select scala.Int.toLong info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi.asInstanceOf[Int].toLong
53 73 2075 - 2154 ApplyToImplicitArgs scala.Array.fill scala.Array.fill[scala.util.Try[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory]](CombinedReadWriteMemory.this.numberModules)(SimpleReadWriteMemory.apply(info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi.asInstanceOf[Int].toLong))((ClassTag.apply[scala.util.Try[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory]](classOf[scala.util.Try]): scala.reflect.ClassTag[scala.util.Try[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory]]))
53 70 2129 - 2130 Literal <nosymbol> 1L
53 69 2091 - 2104 Select info.osdevelopment.sysemu.memory.CombinedReadWriteMemory.numberModules CombinedReadWriteMemory.this.numberModules
53 72 2107 - 2152 Apply info.osdevelopment.sysemu.memory.SimpleReadWriteMemory.apply SimpleReadWriteMemory.apply(info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi.asInstanceOf[Int].toLong)
54 74 2167 - 2167 Apply info.osdevelopment.sysemu.memory.CombinedReadWriteMemory.$anonfun.<init> new $anonfun()
54 75 2075 - 2190 ApplyToImplicitArgs scala.collection.ArrayOps.collect scala.Predef.refArrayOps[scala.util.Try[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory]](scala.Array.fill[scala.util.Try[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory]](CombinedReadWriteMemory.this.numberModules)(SimpleReadWriteMemory.apply(info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi.asInstanceOf[Int].toLong))((ClassTag.apply[scala.util.Try[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory]](classOf[scala.util.Try]): scala.reflect.ClassTag[scala.util.Try[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory]]))).collect[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory](({ @SerialVersionUID(value = 0) final <synthetic> class $anonfun extends scala.runtime.AbstractPartialFunction[scala.util.Try[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory],info.osdevelopment.sysemu.memory.SimpleReadWriteMemory] with java.io.Serializable { def <init>(): <$anon: scala.util.Try[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory] => info.osdevelopment.sysemu.memory.SimpleReadWriteMemory> = { $anonfun.super.<init>(); () }; final override def applyOrElse[A1 <: scala.util.Try[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory], B1 >: info.osdevelopment.sysemu.memory.SimpleReadWriteMemory](x1: A1, default: A1 => B1): B1 = ((x1.asInstanceOf[scala.util.Try[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory]]: scala.util.Try[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory]): scala.util.Try[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory] @unchecked) match { case (value: info.osdevelopment.sysemu.memory.SimpleReadWriteMemory)scala.util.Success[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory]((m @ _)) => m case (defaultCase$ @ _) => default.apply(x1) }; final def isDefinedAt(x1: scala.util.Try[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory]): Boolean = ((x1.asInstanceOf[scala.util.Try[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory]]: scala.util.Try[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory]): scala.util.Try[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory] @unchecked) match { case (value: info.osdevelopment.sysemu.memory.SimpleReadWriteMemory)scala.util.Success[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory]((m @ _)) => true case (defaultCase$ @ _) => false } }; new $anonfun() }: PartialFunction[scala.util.Try[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory],info.osdevelopment.sysemu.memory.SimpleReadWriteMemory]))((ClassTag.apply[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory](classOf[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory]): scala.reflect.ClassTag[info.osdevelopment.sysemu.memory.SimpleReadWriteMemory]))
55 77 2197 - 2228 Apply scala.Int.!= CombinedReadWriteMemory.this.modules.length.!=(CombinedReadWriteMemory.this.numberModules)
55 80 2193 - 2193 Literal <nosymbol> ()
55 76 2215 - 2228 Select info.osdevelopment.sysemu.memory.CombinedReadWriteMemory.numberModules CombinedReadWriteMemory.this.numberModules
55 81 2193 - 2193 Block <nosymbol> ()
56 79 2236 - 2300 Block <nosymbol> throw new java.lang.IllegalStateException("Cannot create ReadWriteMemory")
56 78 2236 - 2300 Throw <nosymbol> throw new java.lang.IllegalStateException("Cannot create ReadWriteMemory")
65 83 2596 - 2600 Select info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong.Gi info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi
65 82 2596 - 2597 Literal <nosymbol> 1L
65 84 2586 - 2600 Apply scala.Long./ address./(info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi)
66 86 2628 - 2632 Select info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong.Gi info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi
66 85 2628 - 2629 Literal <nosymbol> 1L
66 87 2618 - 2632 Apply scala.Long.% address.%(info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi)
67 88 2637 - 2687 Apply info.osdevelopment.sysemu.memory.ReadWriteMemory.readByte CombinedReadWriteMemory.this.modules.apply(module.asInstanceOf[Int]).readByte(offset)
77 89 3022 - 3023 Literal <nosymbol> 1L
77 91 3012 - 3026 Apply scala.Long./ address./(info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi)
77 90 3022 - 3026 Select info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong.Gi info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi
78 92 3054 - 3055 Literal <nosymbol> 1L
78 94 3044 - 3058 Apply scala.Long.% address.%(info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi)
78 93 3054 - 3058 Select info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong.Gi info.osdevelopment.sysemu.support.Utilities.BinaryUnitLong(1L).Gi
79 95 3071 - 3095 TypeApply scala.Any.asInstanceOf module.asInstanceOf[Int]
79 97 3063 - 3139 Apply info.osdevelopment.sysemu.memory.ReadWriteMemory.writeByte CombinedReadWriteMemory.this.modules.apply(module.asInstanceOf[Int]).writeByte(offset.asInstanceOf[Int].toLong, value)
79 96 3107 - 3131 Select scala.Int.toLong offset.asInstanceOf[Int].toLong