Exemple #1
0
        public void VerifyReferenceCount(string dsVariable, int referencCount)
        {
            try
            {
                StackValue sv = testMirror.GetRawFirstValue(dsVariable);

                if (!sv.IsArray && !sv.IsPointer)
                {
                    if (referencCount != 0)
                    {
                        Assert.Fail(String.Format("\t{0} is not a heap element, it doesn't sense to verify its reference count. Should always be 0", dsVariable));
                    }
                }
                else
                {
                    ProtoCore.DSASM.HeapElement he = testMirror.MirrorTarget.rmem.Heap.GetHeapElement(sv);

                    if (he.Refcount != referencCount)
                    {
                        Assert.Fail(String.Format("\t{0}'s reference count is {1}, which is not equal to expected {2}", dsVariable, he.Refcount, referencCount));
                    }
                    else if (referencCount > 0)
                    {
                        if (!he.Active)
                        {
                            Assert.Fail(String.Format("\t{0}'s reference count == {1}, but somehow it is makred as inactive.", dsVariable, referencCount));
                        }
                    }
                }
            }
            catch (NotImplementedException)
            {
                Assert.Fail("\tFailed to get the value of variable " + dsVariable);
            }
        }
Exemple #2
0
        public int Allocate(StackValue[] elements)
        {
            TotalSize += elements.Length;
            HeapElement hpe = new HeapElement(elements);

            return(AddHeapElement(hpe));
        }
Exemple #3
0
        public int GetHashCode(StackValue value)
        {
            if (AddressType.String == value.optype)
            {
                HeapElement he     = ArrayUtils.GetHeapElement(value, core);
                int         length = he.VisibleSize;

                unchecked
                {
                    int hash = 0;
                    int step = (length >> 5) + 1;
                    for (int i = he.VisibleSize; i >= step; i -= step)
                    {
                        hash = (hash * 397) ^ he.Stack[i - 1].opdata.GetHashCode();
                    }
                    return(hash);
                }
            }
            else
            {
                unchecked
                {
                    int hash = 0;
                    hash = (hash * 397) ^ value.opdata.GetHashCode();
                    hash = (hash * 397) ^ value.metaData.type.GetHashCode();
                    return(hash);
                }
            }
        }
Exemple #4
0
        public int Allocate(int size, int symbol = ProtoCore.DSASM.Constants.kInvalidIndex)
        {
            TotalSize += size;
            HeapElement hpe = new HeapElement(size, symbol);

            return(AddHeapElement(hpe));
        }
Exemple #5
0
        private bool TryGetHeapElement(StackValue pointer, out HeapElement heapElement)
        {
            heapElement = null;
            int index = Constants.kInvalidIndex;

            if (pointer.IsPointer)
            {
                index = pointer.Pointer;
            }
            else if (pointer.IsArray)
            {
                index = pointer.ArrayPointer;
            }
            else if (pointer.IsString)
            {
                index = pointer.StringPointer;
            }


            if (index >= 0 && index < heapElements.Count)
            {
                heapElement = heapElements[index];
            }
            return(heapElement != null);
        }
Exemple #6
0
        public void GCRelease(StackValue[] ptrList, Executive exe)
        {
            for (int n = 0; n < ptrList.Length; ++n)
            {
                StackValue svPtr = ptrList[n];
                if (svPtr.optype != AddressType.Pointer && svPtr.optype != AddressType.ArrayPointer)
                {
                    continue;
                }

                int ptr = (int)svPtr.opdata;
                if (ptr < 0 || ptr >= Heaplist.Count)
                {
                    continue;
                }
                HeapElement hs = Heaplist[ptr];

                if (!hs.Active)
                {
                    continue;
                }

                if (hs.Refcount > 0)
                {
                    hs.Refcount--;
                }

                // TODO Jun: If its a pointer to a primitive then dont decrease its refcount, just free it
                // Debug.Assert(hs.refcount >= 0);
                if (hs.Refcount == 0)
                {
                    // if it is of class type, first call its destructor before clean its members
                    if (svPtr.optype == AddressType.Pointer)
                    {
                        GCDisposeObject(ref svPtr, exe);
                    }

                    if (svPtr.optype == AddressType.ArrayPointer && hs.Dict != null)
                    {
                        foreach (var item in hs.Dict)
                        {
                            GCRelease(new StackValue[] { item.Key }, exe);
                            GCRelease(new StackValue[] { item.Value }, exe);
                        }
                    }

                    hs.Dict   = null;
                    hs.Active = false;

                    GCRelease(hs.Stack, exe);
#if _USE_FREE_LIST
                    freeList.Add(ptr);
#endif
                }
            }
        }
Exemple #7
0
        private bool TryGetHeapElement(StackValue pointer, out HeapElement heapElement)
        {
            heapElement = null;
            int index = (int)pointer.opdata;

            if (index >= 0 && index < heapElements.Count)
            {
                heapElement = heapElements[index];
            }
            return heapElement != null;
        }
Exemple #8
0
 /// <summary>
 /// If the heap object is modified, mark the new value that it references to.
 /// </summary>
 /// <param name="hp">Heap object that is to be modified</param>
 /// <param name="value">The value that will be put in the heap object</param>
 public void WriteBarrierForward(HeapElement hp, StackValue value)
 {
     if (hp.Mark == GCMark.Black && value.IsReferenceType)
     {
         HeapElement valueHp;
         if (TryGetHeapElement(value, out valueHp))
         {
             totalTraversed += RecursiveMark(value);
         }
     }
 }
Exemple #9
0
 /// <summary>
 /// Checks if the heap contains at least 1 pointer element that points to itself
 /// This function is used as a diagnostic tool for detecting heap cycles and should never return true
 /// </summary>
 /// <returns> Returns true if the heap contains at least one cycle</returns>
 public bool IsHeapCyclic()
 {
     for (int n = 0; n < heapElements.Count; ++n)
     {
         HeapElement heapElem = heapElements[n];
         if (IsHeapCyclic(heapElem, n))
         {
             return true;
         }
     }
     return false;
 }
Exemple #10
0
        public bool IsTemporaryPointer(StackValue sv)
        {
            if (!StackUtils.IsReferenceType(sv))
            {
                return(false);
            }

            int         ptr = (int)sv.opdata;
            HeapElement he  = this.Heaplist[ptr];

            return(he.Active && he.Refcount == 0);
        }
Exemple #11
0
        // heaper method to support negative index into stack
        public static StackValue GetValue(this HeapElement hs, int ix, Core core)
        {
            int index = ix < 0 ? ix + hs.VisibleSize : ix;

            if (index >= hs.VisibleSize || index < 0)
            {
                core.RuntimeStatus.LogWarning(ProtoCore.Runtime.WarningID.kOverIndexing, Resources.kArrayOverIndexed);
                return(StackValue.Null);
            }

            return(hs.Stack[index]);
        }
Exemple #12
0
        // heaper method to support negative index into stack
        public static StackValue GetValue(this HeapElement hs, int ix, Core core)
        {
            int index = ix < 0 ? ix + hs.VisibleSize : ix;

            if (index >= hs.VisibleSize || index < 0)
            {
                //throw new IndexOutOfRangeException();
                core.RuntimeStatus.LogWarning(ProtoCore.RuntimeData.WarningID.kOverIndexing, RuntimeData.WarningMessage.kArrayOverIndexed);
                return(StackValue.Null);
            }

            return(hs.Stack[index]);
        }
Exemple #13
0
        //this method compares the heap for the stack variables and determines if the values of the heap are same
        private static bool CompareStackValuesFromHeap(StackValue sv1, StackValue sv2, RuntimeCore rtCore1, RuntimeCore rtCore2, ProtoCore.Runtime.Context context)
        {
            HeapElement heap1 = ArrayUtils.GetHeapElement(sv1, rtCore1);
            HeapElement heap2 = ArrayUtils.GetHeapElement(sv2, rtCore2);

            if (heap1.Stack.Length != heap2.Stack.Length)
            {
                return(false);
            }

            for (int i = 0; i < heap1.Stack.Length; i++)
            {
                if (!CompareStackValues(heap1.Stack[i], heap2.Stack[i], rtCore1, rtCore2, context))
                {
                    return(false);
                }
            }

            if (heap1.Dict != null && heap2.Dict != null)
            {
                if (heap1.Dict == heap2.Dict)
                {
                    return(true);
                }

                foreach (var key in heap1.Dict.Keys)
                {
                    StackValue value1 = heap1.Dict[key];
                    StackValue value2 = StackValue.Null;
                    if (!heap2.Dict.TryGetValue(key, out value2))
                    {
                        return(false);
                    }

                    if (!CompareStackValues(value1, value2, rtCore1, rtCore2))
                    {
                        return(false);
                    }
                }

                return(true);
            }
            else if (heap1.Dict == null && heap2.Dict == null)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemple #14
0
        // helper method to support negative index into stack
        public static StackValue SetValue(this HeapElement hs, int ix, StackValue sv)
        {
            if (ix >= hs.GetAllocatedSize())
            {
                throw new System.IndexOutOfRangeException();
            }

            int        index = ix < 0 ? ix + hs.VisibleSize : ix;
            StackValue svOld = hs.Stack[index];

            hs.Stack[index] = sv;

            return(svOld);
        }
Exemple #15
0
        private int AddHeapElement(HeapElement hpe)
        {
            int index = FindFree();

            if (ProtoCore.DSASM.Constants.kInvalidIndex == index)
            {
                Heaplist.Add(hpe);
                index = Heaplist.Count - 1;
            }
            else
            {
                Heaplist[index].Active = true;
                Heaplist[index]        = hpe;
            }
            return(index);
        }
Exemple #16
0
        private int AddHeapElement(HeapElement hpe)
        {
            int index;

            if (TryFindFreeIndex(out index))
            {
                heapElements[index] = hpe;
            }
            else
            {
                heapElements.Add(hpe);
                index = heapElements.Count - 1;
            }

            return(index);
        }
Exemple #17
0
        private int AddHeapElement(HeapElement hpe)
        {
            int index = Constants.kInvalidIndex;

            if (TryFindFreeIndex(out index))
            {
                heapElements[index].Active = true;
                heapElements[index]        = hpe;
            }
            else
            {
                heapElements.Add(hpe);
                index = heapElements.Count - 1;
            }

            return(index);
        }
Exemple #18
0
        private int AddHeapElement(HeapElement hpe)
        {
            hpe.Mark = GCMark.White;
            ReportAllocation(hpe.MemorySize);

            int index;
            if (TryFindFreeIndex(out index))
            {
                heapElements[index] = hpe;
            }
            else
            {
                heapElements.Add(hpe);
                index = heapElements.Count - 1;
            }

            return index;
        }
Exemple #19
0
        public HeapElement Clone()
        {
            HeapElement second = new HeapElement(AllocSize, Symbol);

            second.Active      = Active;
            second.Symbol      = Symbol;
            second.AllocSize   = AllocSize;
            second.VisibleSize = VisibleSize;
            second.Refcount    = Refcount;

            second.Stack = new StackValue[Stack.Length];
            for (int i = 0; i < Stack.Length; i++)
            {
                second.Stack[i] = Stack[i].ShallowClone();
            }

            return(second);
        }
Exemple #20
0
        //this method compares the heap for the stack variables and determines if the values of the heap are same
        private static bool CompareStackValuesFromHeap(StackValue sv1, StackValue sv2, Core c1, Core c2, ProtoCore.Runtime.Context context)
        {
            HeapElement heap1 = c1.Heap.Heaplist[(int)sv1.opdata];
            HeapElement heap2 = c2.Heap.Heaplist[(int)sv2.opdata];

            if (heap1.Stack.Length != heap2.Stack.Length)
            {
                return(false);
            }
            for (int i = 0; i < heap1.Stack.Length; i++)
            {
                if (!CompareStackValues(heap1.Stack[i], heap2.Stack[i], c1, c2, context))
                {
                    return(false);
                }
            }
            return(true);
        }
Exemple #21
0
 /// <summary>
 /// Checks if the heap element is cyclic. 
 /// Traverses the pointer element and determines it points to itself
 /// </summary>
 /// <param name="heapElement"></param>
 /// <param name="core"></param>
 /// <returns> Returns true if the array contains a cycle </returns>
 private static bool IsHeapCyclic(HeapElement heapElement, Core core, int HeapID)
 {
     if (heapElement.Active && heapElement.VisibleSize > 0)
     {
         // Traverse each element in the heap
         foreach (StackValue sv in heapElement.Stack)
         {
             // Is it a pointer
             if (sv.IsReferenceType)
             {
                 // Check if the current element in the heap points to the original pointer
                 if (sv.opdata == HeapID)
                 {
                     return true;
                 }
                 return IsHeapCyclic(core.Heap.Heaplist[(int)sv.opdata], core, HeapID);
             }
         }
     }
     return false;
 }
Exemple #22
0
 /// <summary>
 /// Checks if the heap element is cyclic.
 /// Traverses the pointer element and determines it points to itself
 /// </summary>
 /// <param name="heapElement"></param>
 /// <param name="core"></param>
 /// <returns> Returns true if the array contains a cycle </returns>
 private bool IsHeapCyclic(HeapElement heapElement, int HeapID)
 {
     if (heapElement.VisibleSize > 0)
     {
         // Traverse each element in the heap
         foreach (StackValue sv in heapElement.Stack)
         {
             // Is it a pointer
             if (sv.IsReferenceType)
             {
                 // Check if the current element in the heap points to the original pointer
                 if (sv.opdata == HeapID)
                 {
                     return(true);
                 }
                 return(IsHeapCyclic(GetHeapElement(sv), HeapID));
             }
         }
     }
     return(false);
 }
Exemple #23
0
        public void VerifyReferenceCount(string dsVariable, int referencCount)
        {
            try
            {
                StackValue sv = testMirror.GetRawFirstValue(dsVariable);

                if (!sv.IsArray && !sv.IsPointer)
                {
                    if (referencCount != 0)
                    {
                        Assert.Fail(String.Format("\t{0} is not a heap element, it doesn't sense to verify its reference count. Should always be 0", dsVariable));
                    }
                }
                else
                {
                    ProtoCore.DSASM.HeapElement he = testMirror.MirrorTarget.rmem.Heap.GetHeapElement(sv);
                }
            }
            catch (NotImplementedException)
            {
                Assert.Fail("\tFailed to get the value of variable " + dsVariable);
            }
        }
Exemple #24
0
        private int AllocateInternal(int size, PrimitiveType type)
        {
            HeapElement hpe = null;

            switch (type)
            {
                case PrimitiveType.kTypeArray:
                    hpe = new DSArray(size, this);
                    break;

                case PrimitiveType.kTypePointer:
                    hpe = new DSObject(size, this);
                    break;

                case PrimitiveType.kTypeString:
                    hpe = new DSString(size, this);
                    break;

                default:
                    throw new ArgumentException("type");
            }

            return AddHeapElement(hpe);
        }
Exemple #25
0
        /// <summary>
        /// Checks if the heap element is cyclic. 
        /// Traverses the pointer element and determines it points to itself
        /// </summary>
        /// <param name="heapElement"></param>
        /// <param name="core"></param>
        /// <returns> Returns true if the array contains a cycle </returns>
        private bool IsHeapCyclic(HeapElement heapElement, int HeapID)
        {
            if (heapElement.Count > 0)
            {
                // Traverse each element in the heap
                foreach (StackValue sv in heapElement.Values)
                {
                    // Is it a pointer
                    if (sv.IsReferenceType)
                    {
                        // Check if the current element in the heap points to the original pointer
                        if (sv.opdata == HeapID)
                        {
                            return true;
                        }

                        HeapElement hpe;
                        TryGetHeapElement(sv, out hpe);
                        return IsHeapCyclic(hpe, HeapID);
                    }
                }
            }
            return false;
        }
Exemple #26
0
        private int AllocateInternal(StackValue[] values, PrimitiveType type)
        {
            HeapElement hpe = null;

            switch (type)
            {
            case PrimitiveType.Array:
                hpe = new DSArray(values, this);
                break;

            case PrimitiveType.Pointer:
                hpe = new DSObject(values, this);
                break;

            case PrimitiveType.String:
                hpe = new DSString(values, this);
                break;

            default:
                throw new ArgumentException("type");
            }

            return(AddHeapElement(hpe));
        }
Exemple #27
0
        public void GCRelease(StackValue[] ptrList, Executive exe)
        {
            for (int n = 0; n < ptrList.Length; ++n)
            {
                StackValue svPtr = ptrList[n];
                if (!svPtr.IsPointer && !svPtr.IsArray)
                {
                    continue;
                }

                int ptr = (int)svPtr.opdata;
                if (ptr < 0 || ptr >= heapElements.Count)
                {
#if HEAP_VERIFICATION
                    throw new Exception("Memory corrupted: Release invalid pointer (7364B8C2-FF34-4C67-8DFE-5DFA678BF50D).");
#else
                    continue;
#endif
                }
                HeapElement hs = heapElements[ptr];

                if (!hs.Active)
                {
#if HEAP_VERIFICATION
                    throw new Exception("Memory corrupted: Release dead memory (7F70A6A1-FE99-476E-BE8B-CA7615EE1A3B).");
#else
                    continue;
#endif
                }

                // The reference count could be 0 if this heap object
                // is a temporary heap object that hasn't been assigned
                // to any variable yet, for example, Type.Coerce() may
                // allocate a new array and when this one is type converted
                // again, it will be released.
                if (hs.Refcount > 0)
                {
                    hs.Refcount--;
                }

                // TODO Jun: If its a pointer to a primitive then dont decrease its refcount, just free it
                if (hs.Refcount == 0)
                {
                    // if it is of class type, first call its destructor before clean its members
                    if (svPtr.IsPointer)
                    {
                        GCDisposeObject(svPtr, exe);
                    }

                    if (svPtr.IsArray && hs.Dict != null)
                    {
                        foreach (var item in hs.Dict)
                        {
                            GCRelease(new StackValue[] { item.Key }, exe);
                            GCRelease(new StackValue[] { item.Value }, exe);
                        }
                    }

                    hs.Dict   = null;
                    hs.Active = false;

                    GCRelease(hs.Stack, exe);
#if !HEAP_VERIFICATION
                    freeList.Add(ptr);
#endif
                }
            }
        }
Exemple #28
0
        private int AllocateInternal(int size)
        {
            HeapElement hpe = new HeapElement(size, Constants.kInvalidIndex);

            return(AddHeapElement(hpe));
        }
Exemple #29
0
 public int Allocate(int size, int symbol = ProtoCore.DSASM.Constants.kInvalidIndex)
 {
     TotalSize += size;
     HeapElement hpe = new HeapElement(size, symbol);
     return AddHeapElement(hpe);
 }
Exemple #30
0
 public int Allocate(StackValue[] elements)
 {
     TotalSize += elements.Length;
     HeapElement hpe = new HeapElement(elements);
     return AddHeapElement(hpe);
 }
Exemple #31
0
        public HeapElement Clone()
        {
            HeapElement second = new HeapElement(AllocSize, Symbol);
            second.Active = Active;
            second.Symbol = Symbol;
            second.AllocSize = AllocSize;
            second.VisibleSize = VisibleSize;
            second.Refcount = Refcount;

            second.Stack = new StackValue[Stack.Length];
            for (int i = 0; i < Stack.Length; i++)
                second.Stack[i] = Stack[i].ShallowClone();

            return second;
        }
Exemple #32
0
 private int AddHeapElement(HeapElement hpe)
 {
     int index = FindFree();
     if (ProtoCore.DSASM.Constants.kInvalidIndex == index)
     {
         Heaplist.Add(hpe);
         index = Heaplist.Count - 1;
     }
     else
     {
         Heaplist[index].Active = true;
         Heaplist[index] = hpe;
     }
     return index;
 }