Exemplo n.º 1
0
        /// <summary>
        /// Allocates a section with the given size from the normal free sections.
        /// </summary>
        /// <param name="size">The size of the section to allocate.</param>
        /// <returns>The allocated section.</returns>
        private HeapSection AllocateSection(int size)
        {
            HeapSection currFreeSect = this.freeSectionsHead;

            while (currFreeSect.Length != -1 && currFreeSect.Length < size && currFreeSect != null)
            {
                currFreeSect = currFreeSect.Next;
            }

            if (currFreeSect == null)
            {
                throw new HeapException("Heap is full!");
            }

            if (currFreeSect.Length == size)
            {
                /// Size exactly fits, allocate the section
                if (currFreeSect.Next != null && currFreeSect.Prev != null)
                {
                    /// Non-head
                    currFreeSect.Prev.Next = currFreeSect.Next;
                    currFreeSect.Next.Prev = currFreeSect.Prev;
                    currFreeSect.Next      = null;
                    currFreeSect.Prev      = null;
                }
                else if (currFreeSect.Prev == null && currFreeSect.Next != null)
                {
                    /// Head
                    this.freeSectionsHead  = currFreeSect.Next;
                    currFreeSect.Next.Prev = null;
                    currFreeSect.Next      = null;
                }
                else
                {
                    throw new HeapException("Unexpected case!");
                }

                return(currFreeSect);
            }
            else
            {
                /// Size doesn't fit exactly, need to split the section.
                HeapSection newSection = this.sectionObjectPool.Count != 0
                                          ? this.sectionObjectPool.Dequeue()
                                          : new HeapSection();
                newSection.Address = currFreeSect.Address;
                newSection.Length  = size;
                newSection.Next    = null;
                newSection.Prev    = null;

                currFreeSect.Address = newSection.Address + newSection.Length;
                if (currFreeSect.Length != -1)
                {
                    currFreeSect.Length -= size;
                }
                return(newSection);
            }
        }
Exemplo n.º 2
0
        /// <see cref="IHeapManagerInternals.New"/>
        public IHeapConnector New(short typeID)
        {
            if (this.heap == null)
            {
                throw new InvalidOperationException("No simulation heap created or loaded currently!");
            }
            if (typeID < 0 || typeID >= this.types.Count)
            {
                throw new ArgumentOutOfRangeException("typeID");
            }

            HeapType    type        = this.types[typeID];
            HeapSection sectToAlloc = this.AllocateSection(type.AllocationSize);

            return(this.CreateHeapConnector(sectToAlloc.Address, typeID));
        }
Exemplo n.º 3
0
        /// <see cref="IHeapManagerInternals.NewArray"/>
        public IHeapConnector NewArray(short typeID, int count)
        {
            if (this.heap == null)
            {
                throw new InvalidOperationException("No simulation heap created or loaded currently!");
            }
            if (typeID < 0 || typeID >= this.types.Count)
            {
                throw new ArgumentOutOfRangeException("typeID");
            }
            if (count <= 0)
            {
                throw new ArgumentOutOfRangeException("count");
            }

            HeapType    type        = this.types[typeID];
            HeapSection sectToAlloc = this.AllocateSection(count * type.AllocationSize + 4); /// +4 is for storing the number of array-items.

            this.heap.WriteInt(sectToAlloc.Address, count);
            return(this.CreateHeapConnector(sectToAlloc.Address + 4, typeID));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Deallocates the given simulation heap section.
        /// </summary>
        /// <param name="address">The start address of the section to be deallocated.</param>
        /// <param name="length">The length of the section to be deallocated.</param>
        private void DeallocateSection(int address, int length)
        {
            HeapSection section = this.sectionObjectPool.Count != 0
                          ? this.sectionObjectPool.Dequeue()
                          : new HeapSection();

            section.Address = address;
            section.Length  = length;
            section.Next    = null;
            section.Prev    = null;

            HeapSection currFreeSect = this.freeSectionsHead;

            while (section.Address > currFreeSect.Address)
            {
                currFreeSect = currFreeSect.Next;
            }

            if (section.Address + section.Length < currFreeSect.Address)
            {
                /// Insert the deallocated section before currFreeSect.
                section.Next      = currFreeSect;
                section.Prev      = currFreeSect.Prev;
                currFreeSect.Prev = section;
                if (section.Prev != null)
                {
                    section.Prev.Next = section;
                }
                else
                {
                    this.freeSectionsHead = section;
                }
            }
            else if (section.Address + section.Length == currFreeSect.Address)
            {
                /// Merge the deallocated section with currFreeSect.
                currFreeSect.Address -= section.Length;
                if (currFreeSect.Length != -1)
                {
                    currFreeSect.Length += section.Length;
                }
                this.sectionObjectPool.Enqueue(section);
                section = currFreeSect;
            }
            else
            {
                throw new HeapException("Unexpected case!");
            }

            if (section.Prev != null)
            {
                if (section.Prev.Address + section.Prev.Length == section.Address)
                {
                    /// Merge the section with section.Prev.
                    HeapSection sectToDel = section.Prev;
                    section.Address -= section.Prev.Length;
                    if (section.Length != -1)
                    {
                        section.Length += section.Prev.Length;
                    }
                    section.Prev = section.Prev.Prev;
                    this.sectionObjectPool.Enqueue(sectToDel);
                    if (section.Prev != null)
                    {
                        section.Prev.Next = section;
                    }
                    else
                    {
                        this.freeSectionsHead = section;
                    }
                }
                else if (section.Prev.Address + section.Prev.Length > section.Address)
                {
                    throw new HeapException("Unexpected case!");
                }
            }
        }