Exemple #1
0
        public static tMD_MethodDef *GetMethodDefFromSpec(tMD_MethodSpec *pMethodSpec,
                                                          tMD_TypeDef **ppCallingClassTypeArgs, tMD_TypeDef **ppCallingMethodTypeArgs)
        {
            tMD_MethodDef *pCoreMethod;
            tMD_MethodDef *pMethod;
            /*SIG*/ byte * sig;
            uint           argCount, i;
            tMD_TypeDef ** ppTypeArgs;

            Mem.heapcheck();

            pCoreMethod = MetaData.GetMethodDefFromDefRefOrSpec(pMethodSpec->pMetaData, pMethodSpec->method,
                                                                null, null);//ppCallingClassTypeArgs, ppCallingMethodTypeArgs);

            //ppClassTypeArgs = pCoreMethod->pParentType->ppClassTypeArgs;
            sig = MetaData.GetBlob(pMethodSpec->instantiation, null);
            MetaData.DecodeSigEntry(&sig);     // always 0x0a
            argCount   = MetaData.DecodeSigEntry(&sig);
            ppTypeArgs = (tMD_TypeDef **)Mem.malloc((SIZE_T)(argCount * sizeof(tMD_TypeDef *)));

            for (i = 0; i < argCount; i++)
            {
                tMD_TypeDef *pArgType;

                pArgType      = Type.GetTypeFromSig(pMethodSpec->pMetaData, &sig, ppCallingClassTypeArgs, ppCallingMethodTypeArgs, null);
                ppTypeArgs[i] = pArgType;
            }

            pMethod = Generics.GetMethodDefFromCoreMethod(pCoreMethod, pCoreMethod->pParentType, argCount, ppTypeArgs);
            Mem.free(ppTypeArgs);

            Mem.heapcheck();

            return(pMethod);
        }
Exemple #2
0
        public static tMD_TypeDef *GetGenericTypeFromSig(tMetaData *pMetaData, /*SIG*/ byte **pSig,
                                                         tMD_TypeDef **ppCallingClassTypeArgs, tMD_TypeDef **ppCallingMethodTypeArgs)
        {
            tMD_TypeDef * pCoreType;
            tMD_TypeDef * pRet;
            uint          numTypeArgs, i;
            tMD_TypeDef **ppTypeArgs;

            Mem.heapcheck();

            pCoreType = Type.GetTypeFromSig(pMetaData, pSig, ppCallingClassTypeArgs, ppCallingMethodTypeArgs, null);
            MetaData.Fill_TypeDef(pCoreType, ppCallingClassTypeArgs, ppCallingMethodTypeArgs, Type.TYPE_FILL_PARENTS);     //null, null);

            numTypeArgs = MetaData.DecodeSigEntry(pSig);
            ppTypeArgs  = (tMD_TypeDef **)Mem.malloc((SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *)));
            for (i = 0; i < numTypeArgs; i++)
            {
                ppTypeArgs[i] = Type.GetTypeFromSig(pMetaData, pSig, ppCallingClassTypeArgs, ppCallingMethodTypeArgs);
                if (ppTypeArgs[i] != null)
                {
                    MetaData.Fill_TypeDef(ppTypeArgs[i], null, null, Type.TYPE_FILL_PARENTS);
                }
            }

            pRet = GetGenericTypeFromCoreType(pCoreType, numTypeArgs, ppTypeArgs);
            Mem.free(ppTypeArgs);

            Mem.heapcheck();

            return(pRet);
        }
Exemple #3
0
        public static byte *strdup(byte *s)
        {
            Mem.heapcheck();
            int   len = strlen(s) + 1;
            byte *p   = (byte *)Mem.malloc((SIZE_T)len);

            strncpy(p, s, len);
            return(p);
        }
Exemple #4
0
        public static tMD_MethodDef *GetMethodDefFromCoreMethod(tMD_MethodDef *pCoreMethod,
                                                                tMD_TypeDef *pParentType, uint numTypeArgs, tMD_TypeDef **ppTypeArgs,
                                                                HashSet <PTR> resolveTypes = null)
        {
            tGenericMethodInstance *pInst;
            tMD_MethodDef *         pMethod;
            int i;

            Mem.heapcheck();

            // See if we already have an instance with the given type args
            pInst = pCoreMethod->pGenericMethodInstances;
            while (pInst != null)
            {
                if (pInst->numTypeArgs == numTypeArgs &&
                    Mem.memcmp(pInst->ppTypeArgs, ppTypeArgs, (SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *))) == 0)
                {
                    return(pInst->pInstanceMethodDef);
                }
                pInst = pInst->pNext;
            }

            // We don't have an instance so create one now.
            pInst        = (tGenericMethodInstance *)Mem.mallocForever((SIZE_T)(sizeof(tGenericMethodInstance)));
            pInst->pNext = pCoreMethod->pGenericMethodInstances;
            pCoreMethod->pGenericMethodInstances = pInst;
            pInst->numTypeArgs = numTypeArgs;
            pInst->ppTypeArgs  = (tMD_TypeDef **)Mem.malloc((SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *)));
            Mem.memcpy(pInst->ppTypeArgs, ppTypeArgs, (SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *)));

            pInst->pInstanceMethodDef = pMethod = ((tMD_MethodDef *)Mem.mallocForever((SIZE_T)sizeof(tMD_MethodDef)));
            Mem.memset(pMethod, 0, (SIZE_T)sizeof(tMD_MethodDef));
            pMethod->pMethodDef       = pMethod;
            pMethod->pMetaData        = pCoreMethod->pMetaData;
            pMethod->pCIL             = pCoreMethod->pCIL;
            pMethod->implFlags        = pCoreMethod->implFlags;
            pMethod->flags            = pCoreMethod->flags;
            pMethod->name             = pCoreMethod->name;
            pMethod->signature        = pCoreMethod->signature;
            pMethod->vTableOfs        = pCoreMethod->vTableOfs;
            pMethod->ppMethodTypeArgs = pInst->ppTypeArgs;

            MetaData.Fill_MethodDef(pParentType, pMethod, pParentType->ppClassTypeArgs, pInst->ppTypeArgs);

            Mem.heapcheck();

            return(pMethod);
        }
Exemple #5
0
        public static int Execute()
        {
            Mem.heapcheck();
            int returnCode = 0;

            for (;;)
            {
                uint status = Thread.Update(maxInstrPerThread, &returnCode);
                if (status == THREADSTATE_STOPPED)
                {
                    break;
                }
            }
            Mem.heapcheck();
            return(returnCode);
        }
Exemple #6
0
        public static DnaObject CreateInstance(tMD_TypeDef *pTypeDef, object monoBaseObject = null)
        {
            Mem.heapcheck();
            byte *pPtr = null;

            if (monoBaseObject != null)
            {
                pPtr = Heap.AllocMonoObject(pTypeDef, monoBaseObject);
            }
            else
            {
                pPtr = Heap.AllocType(pTypeDef);
            }
            Mem.heapcheck();
            return(WrapObject(pPtr));
        }
Exemple #7
0
        public static tMethodState *Direct(tThread *pThread, tMD_MethodDef *pMethod, tMethodState *pCaller, uint isInternalNewObjCall)
        {
            tMethodState *pThis;

            Mem.heapcheck();

            if (pMethod->isFilled == 0)
            {
                tMD_TypeDef *pTypeDef;

                pTypeDef = MetaData.GetTypeDefFromMethodDef(pMethod);
                MetaData.Fill_TypeDef(pTypeDef, null, null);
            }

            pThis = (tMethodState *)Thread.StackAlloc(pThread, (uint)sizeof(tMethodState));
            pThis->finalizerThis = null;
            pThis->pCaller       = pCaller;
            pThis->pMetaData     = pMethod->pMetaData;
            pThis->pMethod       = pMethod;
            if (pMethod->pJITted == null)
            {
                // If method has not already been JITted
                JIT.Prepare(pMethod, 0);
            }
            pThis->pJIT                 = pMethod->pJITted;
            pThis->ipOffset             = 0;
            pThis->pEvalStack           = (byte *)Thread.StackAlloc(pThread, pThis->pMethod->pJITted->maxStack);
            pThis->stackOfs             = 0;
            pThis->isInternalNewObjCall = isInternalNewObjCall;
            pThis->pNextDelegate        = null;
            pThis->pDelegateParams      = null;

            pThis->pParamsLocals = (byte *)Thread.StackAlloc(pThread, pMethod->parameterStackSize + pMethod->pJITted->localsStackSize);
            Mem.memset(pThis->pParamsLocals, 0, pMethod->parameterStackSize + pMethod->pJITted->localsStackSize);

#if DIAG_METHOD_CALLS
            // Keep track of the number of times this method is called
            pMethod->callCount++;
            pThis->startTime = microTime();
#endif

            Mem.heapcheck();

            return(pThis);
        }
Exemple #8
0
        public static byte *strncat(byte *a, string b, int size)
        {
            Mem.heapcheck();
            if (a == null || b == null)
            {
                throw new System.NullReferenceException();
            }
            byte *dst = a;
            int   len = strlen(a);

            if (len + 1 >= size)
            {
                throw new System.IndexOutOfRangeException();
            }
            strncpy(a + len, b, size - len);
            Mem.heapcheck();
            return(dst);
        }
Exemple #9
0
        public static byte *strncpy(byte *a, byte *b, int size)
        {
            Mem.heapcheck();
            if (a == null || b == null)
            {
                throw new System.NullReferenceException();
            }
            byte *dst = a;
            byte *end = a + (size - 1);

            while (*b != 0)
            {
                if (a >= end)
                {
                    throw new System.IndexOutOfRangeException();
                }
                *a++ = *b++;
            }
            *a = 0;
            Mem.heapcheck();
            return(dst);
        }
Exemple #10
0
        public static byte *strncpy(byte *a, string b, int size)
        {
            Mem.heapcheck();
            if (a == null || b == null)
            {
                throw new System.NullReferenceException();
            }
            byte *dst = a;
            byte *end = a + (size - 1);
            int   len = b.Length;

            for (int i = 0; i < len; i++)
            {
                if (a >= end)
                {
                    throw new System.IndexOutOfRangeException();
                }
                *a++ = (byte)b[i];
            }
            *a = 0;
            Mem.heapcheck();
            return(dst);
        }
Exemple #11
0
        public static byte *scatprintf(byte *bfr, byte *end, string fmt, params object[] args)
        {
            if (bfr == null || fmt == null)
            {
                throw new System.NullReferenceException();
            }
            Mem.heapcheck();
            int   curarg = 0;
            int   i      = 0;
            int   fmtLen = fmt.Length;
            byte *b      = bfr;
            byte *e      = end;

            while (i < fmtLen)
            {
                char ch = fmt[i];
                if (ch == '%' && i + 1 < fmtLen)
                {
                    i++;
                    ch = fmt[i];
                    if (ch == 's')
                    {
                        object sarg = args[curarg];
                        curarg++;
                        if (sarg == null)
                        {
                            if (b + 4 > e)
                            {
                                throw new System.IndexOutOfRangeException();
                            }
                            *b++ = (byte)'n';
                            *b++ = (byte)'u';
                            *b++ = (byte)'l';
                            *b++ = (byte)'l';
                        }
                        else if (sarg is string)
                        {
                            string str = (string)sarg;
                            for (int j = 0; j < str.Length; j++)
                            {
                                if (b >= e)
                                {
                                    throw new System.IndexOutOfRangeException();
                                }
                                *b++ = (byte)str[j];
                            }
                        }
                        else if (sarg is PTR)
                        {
                            byte *s = (byte *)((PTR)sarg);
                            if (s == null)
                            {
                                if (b + 4 >= e)
                                {
                                    throw new System.IndexOutOfRangeException();
                                }
                                *b++ = (byte)'n';
                                *b++ = (byte)'u';
                                *b++ = (byte)'l';
                                *b++ = (byte)'l';
                            }
                            else
                            {
                                while (*s != 0)
                                {
                                    if (b >= e)
                                    {
                                        throw new System.IndexOutOfRangeException();
                                    }
                                    *b++ = *s++;
                                }
                            }
                        }
                        else
                        {
                            throw new System.ArgumentException();
                        }
                    }
                    else if (ch == 'x' || ch == 'X' || ch == 'd')
                    {
                        int    v;
                        object arg = args[curarg];
                        if (arg is int)
                        {
                            v = (int)arg;
                        }
                        else if (arg is uint)
                        {
                            v = (int)(uint)arg;
                        }
                        else if (arg is long)
                        {
                            v = (int)(long)arg;
                        }
                        else if (arg is ulong)
                        {
                            v = (int)(ulong)arg;
                        }
                        else
                        {
                            v = System.Convert.ToInt32(arg);
                        }
                        curarg++;
                        string vs = (ch == 'x' || ch == 'X' ? v.ToString("X") : v.ToString());
                        for (int j = 0; j < vs.Length; j++)
                        {
                            if (b >= e)
                            {
                                throw new System.IndexOutOfRangeException();
                            }
                            *b++ = (byte)vs[j];
                        }
                    }
                    else if (ch == 'l' && i + 2 < fmtLen && fmt[i + 1] == 'l' && (fmt[i + 2] == 'x' || fmt[i + 2] == 'X' || fmt[i + 2] == 'd'))
                    {
                        i += 2;
                        ch = fmt[i];
                        long lv = System.Convert.ToInt64(args[curarg]);
                        curarg++;
                        string lvs = (ch == 'x' || ch == 'X' ? lv.ToString("X") : lv.ToString());
                        for (int j = 0; j < lvs.Length; j++)
                        {
                            if (b >= e)
                            {
                                throw new System.IndexOutOfRangeException();
                            }
                            *b++ = (byte)lvs[j];
                        }
                    }
                    else if (ch == '0' && i + 2 < fmtLen && (fmt[i + 1] >= '0' && fmt[i + 1] <= '9') && (fmt[i + 2] == 'x' || fmt[i + 2] == 'X' || fmt[i + 2] == 'd'))
                    {
                        char l0 = fmt[i + 1];
                        i += 2;
                        ch = fmt[i];
                        int    v0;
                        object arg = args[curarg];
                        if (arg is int)
                        {
                            v0 = (int)arg;
                        }
                        else if (arg is uint)
                        {
                            v0 = (int)(uint)arg;
                        }
                        else if (arg is long)
                        {
                            v0 = (int)(long)arg;
                        }
                        else if (arg is ulong)
                        {
                            v0 = (int)(ulong)arg;
                        }
                        else
                        {
                            v0 = System.Convert.ToInt32(arg);
                        }
                        curarg++;
                        string vs0 = (ch == 'x' || ch == 'X' ? v0.ToString("X" + l0) : v0.ToString("D" + l0));
                        for (int j = 0; j < vs0.Length; j++)
                        {
                            if (b >= e)
                            {
                                throw new System.IndexOutOfRangeException();
                            }
                            *b++ = (byte)vs0[j];
                        }
                    }
                    else
                    {
                        if (b >= e)
                        {
                            throw new System.IndexOutOfRangeException();
                        }
                        *b++ = (byte)ch;
                    }
                }
                else
                {
                    if (b >= e)
                    {
                        throw new System.IndexOutOfRangeException();
                    }
                    *b++ = (byte)ch;
                }
                i++;
            }

            // Null terminator
            *b = 0;

            Mem.heapcheck();

            return(b);
        }
Exemple #12
0
        public static tMD_TypeDef *GetGenericTypeFromCoreType(tMD_TypeDef *pCoreType, uint numTypeArgs,
                                                              tMD_TypeDef **ppTypeArgs)
        {
            tGenericInstance *pInst;
            tMD_TypeDef *     pTypeDef;
            uint       i;
            byte *     name = stackalloc byte[NAME_BUF_SIZE];
            byte *     namePos, nameEnd;
            tMetaData *pMetaData;

            Mem.heapcheck();

            pMetaData = pCoreType->pMetaData;
            MetaData.Fill_TypeDef(pCoreType, null, null, Type.TYPE_FILL_PARENTS);

            // See if we have already built an instantiation of this type with the given type args.
            pInst = pCoreType->pGenericInstances;
            while (pInst != null)
            {
                if (pInst->numTypeArgs == numTypeArgs &&
                    Mem.memcmp(pInst->ppTypeArgs, ppTypeArgs, (SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *))) == 0)
                {
                    return(pInst->pInstanceTypeDef);
                }
                pInst = pInst->pNext;
            }

            // This has not already been instantiated, so instantiate it now.
            pInst = (tGenericInstance *)Mem.mallocForever((SIZE_T)sizeof(tGenericInstance));
            // Insert this into the chain of instantiations.
            pInst->pNext = pCoreType->pGenericInstances;
            pCoreType->pGenericInstances = pInst;
            // Copy the type args into the instantiation.
            pInst->numTypeArgs = numTypeArgs;
            pInst->ppTypeArgs  = (tMD_TypeDef **)Mem.malloc((SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *)));
            Mem.memcpy(pInst->ppTypeArgs, ppTypeArgs, (SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *)));

            Mem.heapcheck();

            // Create the new instantiated type
            pInst->pInstanceTypeDef = pTypeDef = ((tMD_TypeDef *)Mem.mallocForever((SIZE_T)sizeof(tMD_TypeDef)));
            Mem.memset(pTypeDef, 0, (SIZE_T)sizeof(tMD_TypeDef));
            // Make the name of the instantiation.
            namePos = name;
            nameEnd = namePos + NAME_BUF_SIZE - 1;
            namePos = S.scatprintf(namePos, nameEnd, "%s", (PTR)pCoreType->name);
            namePos = S.scatprintf(namePos, nameEnd, "[");
            for (i = 0; i < numTypeArgs; i++)
            {
                if (i > 0)
                {
                    namePos = S.scatprintf(namePos, nameEnd, ",");
                }
                if (ppTypeArgs[i] != null)
                {
                    namePos = S.scatprintf(namePos, nameEnd, "%s.%s", (PTR)ppTypeArgs[i]->nameSpace, (PTR)ppTypeArgs[i]->name);
                }
                else
                {
                    tMD_GenericParam *pGenericParam = FindGenericParam(pCoreType, i);
                    if (pGenericParam != null)
                    {
                        namePos = S.scatprintf(namePos, nameEnd, "%s", (PTR)pGenericParam->name);
                    }
                    else
                    {
                        namePos = S.scatprintf(namePos, nameEnd, "???");
                    }
                }
            }
            namePos = S.scatprintf(namePos, nameEnd, "]");
            // Fill in the basic bits of the new type def.
            pTypeDef->pTypeDef           = pTypeDef;
            pTypeDef->pMetaData          = pMetaData;
            pTypeDef->flags              = pCoreType->flags;
            pTypeDef->pGenericDefinition = pCoreType;
            for (i = 0; i < numTypeArgs; i++)
            {
                if (ppTypeArgs[i] == null)
                {
                    pTypeDef->isGenericDefinition = 1;
                    break;
                }
            }
            pTypeDef->nameSpace = pCoreType->nameSpace;
            int nameLen = S.strlen(name) + 1;

            pTypeDef->name = (/*STRING*/ byte *)Mem.mallocForever((SIZE_T)nameLen);
            S.strncpy(pTypeDef->name, name, nameLen);
            pTypeDef->ppClassTypeArgs   = pInst->ppTypeArgs;
            pTypeDef->extends           = pCoreType->extends;
            pTypeDef->tableIndex        = pCoreType->tableIndex;
            pTypeDef->fieldList         = pCoreType->fieldList;
            pTypeDef->methodList        = pCoreType->methodList;
            pTypeDef->numFields         = pCoreType->numFields;
            pTypeDef->numMethods        = pCoreType->numMethods;
            pTypeDef->numVirtualMethods = pCoreType->numVirtualMethods;
            pTypeDef->pNestedIn         = pCoreType->pNestedIn;
            pTypeDef->isPrimed          = 1;

            MetaData.Fill_TypeDef(pTypeDef, pInst->ppTypeArgs, null, Type.TYPE_FILL_PARENTS);

            Mem.heapcheck();

            return(pTypeDef);
        }
Exemple #13
0
        public static void GarbageCollect()
        {
#if NO
            tHeapRoots   heapRoots;
            tHeapEntry * pNode;
            tHeapEntry **pUp = stackalloc tHeapEntry *[MAX_TREE_DEPTH * 2];
            int          top;
            tHeapEntry * pToDelete   = null;
            SIZE_T       orgHeapSize = trackHeapSize;
            uint         orgNumNodes = numNodes;
            #if DIAG_GC
            ulong startTime;
            #endif

            Mem.heapcheck();

            numCollections++;

        #if DIAG_GC
            startTime = microTime();
        #endif

            heapRoots.capacity     = 64;
            heapRoots.num          = 0;
            heapRoots.pHeapEntries = (tHeapRootEntry *)Mem.malloc(heapRoots.capacity * (SIZE_T)sizeof(tHeapRootEntry));

            Thread.GetHeapRoots(&heapRoots);
            CLIFile.GetHeapRoots(&heapRoots);

            // Mark phase
            while (heapRoots.num > 0)
            {
                tHeapRootEntry *pRootsEntry;
                uint            i;
                uint            moreRootsAdded = 0;
                uint            rootsEntryNumPointers;
                void **         pRootsEntryMem;

                // Get a piece of memory off the list of heap memory roots.
                pRootsEntry           = &heapRoots.pHeapEntries[heapRoots.num - 1];
                rootsEntryNumPointers = pRootsEntry->numPointers;
                pRootsEntryMem        = pRootsEntry->pMem;
                // Mark this entry as done
                pRootsEntry->numPointers = 0;
                pRootsEntry->pMem        = null;
                // Iterate through all pointers in it
                for (i = 0; i < rootsEntryNumPointers; i++)
                {
                    void *pMemRef = pRootsEntryMem[i];
                    // Quick escape for known non-memory
                    if (pMemRef == null)
                    {
                        continue;
                    }
                    // Find this piece of heap memory in the tracking tree.
                    // Note that the 2nd memory address comparison MUST be >, not >= as might be expected,
                    // to allow for a zero-sized memory to be detected (and not garbage collected) properly.
                    // E.g. The object class has zero memory.
                    pNode = pHeapTreeRoot;
                    while (pNode != nil)
                    {
                        if (pMemRef < (void *)pNode)
                        {
                            pNode = (tHeapEntry *)pNode->pLink[0];
                        }
                        else if ((byte *)pMemRef > ((byte *)pNode) + GetSize(pNode) + sizeof(tHeapEntry))
                        {
                            pNode = (tHeapEntry *)pNode->pLink[1];
                        }
                        else
                        {
                            // Found memory. See if it's already been marked.
                            // If it's already marked, then don't do anything.
                            // It it's not marked, then add all of its memory to the roots, and mark it.
                            if (pNode->marked == 0)
                            {
                                tMD_TypeDef *pType = pNode->pTypeDef;

                                // Not yet marked, so mark it, and add it to heap roots.
                                pNode->marked = 1;

                                // Don't look at the contents of strings, arrays of primitive Type.types, or WeakReferences
                                if (pType->stackType == EvalStack.EVALSTACK_O ||
                                    pType->stackType == EvalStack.EVALSTACK_VALUETYPE ||
                                    pType->stackType == EvalStack.EVALSTACK_PTR)
                                {
                                    if (pType != Type.types[Type.TYPE_SYSTEM_STRING] &&
                                        (!MetaData.TYPE_ISARRAY(pType) ||
                                         pType->pArrayElementType->stackType == EvalStack.EVALSTACK_O ||
                                         pType->pArrayElementType->stackType == EvalStack.EVALSTACK_VALUETYPE ||
                                         pType->pArrayElementType->stackType == EvalStack.EVALSTACK_PTR))
                                    {
                                        if (pType != Type.types[Type.TYPE_SYSTEM_WEAKREFERENCE])
                                        {
                                            Heap.SetRoots(&heapRoots, ((byte *)&pNode->pSync + sizeof(PTR)), GetSize(pNode));
                                            moreRootsAdded = 1;
                                        }
                                    }
                                }
                            }
                            break;
                        }
                    }
                }
                if (moreRootsAdded == 0)
                {
                    heapRoots.num--;
                }
            }

            Mem.free(heapRoots.pHeapEntries);

            // Sweep phase
            // Traverse nodes
            pUp[0] = pHeapTreeRoot;
            top    = 1;
            while (top != 0)
            {
                // Get this node
                pNode = pUp[--top];
                // Act on this node
                if (pNode->marked != 0)
                {
                    if (pNode->marked != 0xff)
                    {
                        // Still in use (but not marked undeletable), so unmark
                        pNode->marked = 0;
                    }
                }
                else
                {
                    // Not in use any more, so put in deletion queue if it does not need Finalizing
                    // If it does need Finalizing, then don't garbage collect, and put in Finalization queue.
                    if (pNode->needToFinalize != 0)
                    {
                        if (pNode->needToFinalize == 1)
                        {
                            Finalizer.AddFinalizer((/*HEAP_PTR*/ byte *)pNode + sizeof(tHeapEntry));
                            // Mark it has having been placed in the finalization queue.
                            // When it has been finalized, then this will be set to 0
                            pNode->needToFinalize = 2;
                            // If this object is being targetted by weak-ref(s), handle it
                            if (pNode->pSync != null)
                            {
                                RemoveWeakRefTarget(pNode, 0);
                                Mem.free(pNode->pSync);
                            }
                        }
                    }
                    else
                    {
                        // If this object is being targetted by weak-ref(s), handle it
                        if (pNode->pSync != null)
                        {
                            RemoveWeakRefTarget(pNode, 1);
                            Mem.free(pNode->pSync);
                        }
                        // Use pSync to point to next entry in this linked-list.
                        pNode->pSync = (tSync *)pToDelete;
                        pToDelete    = pNode;
                    }
                }
                // Get next node(s)
                if (pNode->pLink[1] != (PTR)nil)
                {
                    pUp[top++] = (tHeapEntry *)pNode->pLink[1];
                }
                if (pNode->pLink[0] != (PTR)nil)
                {
                    pUp[top++] = (tHeapEntry *)pNode->pLink[0];
                }
            }

            // Delete all unused memory nodes.
            while (pToDelete != null)
            {
                tHeapEntry *pThis = pToDelete;
                pToDelete     = (tHeapEntry *)(pToDelete->pSync);
                pHeapTreeRoot = TreeRemove(pHeapTreeRoot, pThis);
                if (pThis->monoHandle == 1)
                {
                    void *hptr = *(void **)((byte *)pThis + sizeof(tHeapEntry));
                    if (hptr != null)
                    {
                        H.Free(hptr);
                    }
                }
                numNodes--;
                trackHeapSize -= GetSize(pThis) + (uint)sizeof(tHeapEntry);
                Mem.free(pThis);
            }

            Mem.heapcheck();

        #if DIAG_GC
            gcTotalTime += microTime() - startTime;
        #endif

            Sys.log_f(1, "--- GARBAGE --- [Size: %d -> %d] [Nodes: %d -> %d]\n",
                      orgHeapSize, trackHeapSize, orgNumNodes, numNodes);

        #if DIAG_GC
            Sys.log_f(1, "GC time = %d ms\n", gcTotalTime / 1000);
        #endif
            #endif
        }
Exemple #14
0
        public static tMD_MethodDef *GetMethodDefFromCoreMethod(tMD_MethodDef *pCoreMethod,
                                                                tMD_TypeDef *pParentType, uint numTypeArgs, tMD_TypeDef **ppTypeArgs,
                                                                HashSet <PTR> resolveTypes = null)
        {
            tGenericMethodInstance *pInst;
            tMD_MethodDef *         pMethod;

            Mem.heapcheck();

            // See if we already have an instance with the given type args
            pInst = pCoreMethod->pGenericMethodInstances;
            while (pInst != null)
            {
                if (pInst->numTypeArgs == numTypeArgs &&
                    Mem.memcmp(pInst->ppTypeArgs, ppTypeArgs, (SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *))) == 0)
                {
                    return(pInst->pInstanceMethodDef);
                }
                pInst = pInst->pNext;
            }

            // We don't have an instance so create one now.
            pInst        = (tGenericMethodInstance *)Mem.mallocForever((SIZE_T)(sizeof(tGenericMethodInstance)));
            pInst->pNext = pCoreMethod->pGenericMethodInstances;
            pCoreMethod->pGenericMethodInstances = pInst;
            pInst->numTypeArgs = numTypeArgs;
            pInst->ppTypeArgs  = (tMD_TypeDef **)Mem.malloc((SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *)));
            Mem.memcpy(pInst->ppTypeArgs, ppTypeArgs, (SIZE_T)(numTypeArgs * sizeof(tMD_TypeDef *)));

            pInst->pInstanceMethodDef = pMethod = ((tMD_MethodDef *)Mem.mallocForever((SIZE_T)sizeof(tMD_MethodDef)));
            Mem.memset(pMethod, 0, (SIZE_T)sizeof(tMD_MethodDef));
            pMethod->pMethodDef       = pMethod;
            pMethod->pMetaData        = pCoreMethod->pMetaData;
            pMethod->pCIL             = pCoreMethod->pCIL;
            pMethod->implFlags        = pCoreMethod->implFlags;
            pMethod->flags            = pCoreMethod->flags;
            pMethod->name             = pCoreMethod->name;
            pMethod->signature        = pCoreMethod->signature;
            pMethod->vTableOfs        = pCoreMethod->vTableOfs;
            pMethod->ppMethodTypeArgs = pInst->ppTypeArgs;

            if (pCoreMethod->monoMethodInfo != null)
            {
                System.Reflection.MethodInfo methodInfo = H.ToObj(pCoreMethod->monoMethodInfo) as System.Reflection.MethodInfo;
                System.Type[] typeArgs = new System.Type[(int)numTypeArgs];
                for (uint i = 0; i < numTypeArgs; i++)
                {
                    typeArgs[i] = MonoType.GetMonoTypeForType(ppTypeArgs[i]);
                    if (typeArgs[i] == null)
                    {
                        Sys.Crash("Unable to find mono type for type arg %s.%s in for generic method %s",
                                  (PTR)ppTypeArgs[i]->nameSpace, (PTR)ppTypeArgs[i]->name, (PTR)pCoreMethod->name);
                    }
                }
                System.Reflection.MethodInfo genericMethodInfo = methodInfo.MakeGenericMethod(typeArgs);
                MonoType.Fill_MethodDef(pParentType, genericMethodInfo, pMethod, pParentType->ppClassTypeArgs, pInst->ppTypeArgs);
            }
            else
            {
                MetaData.Fill_MethodDef(pParentType, pMethod, pParentType->ppClassTypeArgs, pInst->ppTypeArgs);
            }

            Mem.heapcheck();

            return(pMethod);
        }