static int InternalLoadAndRun(bool tryRun, string[] args) { if (!_isInitialized) { Init(); } /*char**/ byte *pFileName = new S(args[0]); tCLIFile * pCLIFile; int retValue; #if DIAG_TOTAL_TIME ulong startTime; #endif #if DIAG_OPCODE_TIMES Mem.memset(opcodeTimes, 0, sizeof(opcodeTimes)); #endif #if DIAG_OPCODE_USE Mem.memset(opcodeNumUses, 0, sizeof(opcodeNumUses)); #endif pCLIFile = CLIFile.LoadAssembly(pFileName); #if DIAG_TOTAL_TIME startTime = microTime(); #endif if (tryRun) { if (pCLIFile->entryPoint != 0) { retValue = CLIFile.Execute(pCLIFile, args); } else { Sys.printf("File %s has no entry point, skipping execution\n", (PTR)pFileName); retValue = 0; } } else { retValue = 0; } #if DIAG_TOTAL_TIME printf("Total execution time = %d ms\n", (int)((microTime() - startTime) / 1000)); #endif #if DIAG_GC printf("Total GC time = %d ms\n", (int)(Heap.gcTotalTime / 1000)); #endif #if DIAG_METHOD_CALLS { uint numMethods, i; int howMany = 25; tMetaData *pCorLib; // Report on most-used methods pCorLib = CLIFile_GetMetaDataForAssembly("mscorlib"); numMethods = pCorLib->tables.numRows[MetaDataTable.MD_TABLE_METHODDEF]; printf("\nCorLib method usage:\n"); for (; howMany > 0; howMany--) { tMD_MethodDef *pMethod; uint maxCount = 0, maxIndex = 0; for (i = 1; i <= numMethods; i++) { pMethod = (tMD_MethodDef *)MetaData.GetTableRow(pCorLib, MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_METHODDEF, i)); if (pMethod->callCount > maxCount) { maxCount = pMethod->callCount; maxIndex = i; } } pMethod = (tMD_MethodDef *)MetaData.GetTableRow(pCorLib, MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_METHODDEF, maxIndex)); printf("%d: %s (%d)\n", (int)pMethod->callCount, Sys_GetMethodDesc(pMethod), (int)(pMethod->totalTime / 1000)); pMethod->callCount = 0; } printf("\n"); } { uint numMethods, i; int howMany = 25; tMetaData *pCorLib; // Report on most-used methods pCorLib = CLIFile_GetMetaDataForAssembly("mscorlib"); numMethods = pCorLib->tables.numRows[MetaDataTable.MD_TABLE_METHODDEF]; printf("\nCorLib method execution time:\n"); for (; howMany > 0; howMany--) { tMD_MethodDef *pMethod; ulong maxTime = 0; uint maxIndex = 0; for (i = 1; i <= numMethods; i++) { pMethod = (tMD_MethodDef *)MetaData.GetTableRow(pCorLib, MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_METHODDEF, i)); if (pMethod->totalTime > maxTime) { maxTime = pMethod->totalTime; maxIndex = i; } } pMethod = (tMD_MethodDef *)MetaData.GetTableRow(pCorLib, MetaData.MAKE_TABLE_INDEX(MetaDataTable.MD_TABLE_METHODDEF, maxIndex)); printf("%d: %s (%d)\n", (int)pMethod->callCount, Sys_GetMethodDesc(pMethod), (int)(pMethod->totalTime / 1000)); pMethod->totalTime = 0; } printf("\n"); } #endif #if DIAG_OPCODE_TIMES { int howMany = 25; uint i; printf("\nOpCodes execution time:\n"); for (; howMany > 0; howMany--) { ulong maxTime = 0; uint maxIndex = 0; for (i = 0; i < JitOps.JIT_OPCODE_MAXNUM; i++) { if (opcodeTimes[i] > maxTime) { maxTime = opcodeTimes[i]; maxIndex = i; } } printf("0x%03x: %dms (used %d times) (ave = %d)\n", maxIndex, (int)(maxTime / 1000), (int)opcodeNumUses[maxIndex], (int)(maxTime / opcodeNumUses[maxIndex])); opcodeTimes[maxIndex] = 0; } } #endif #if DIAG_OPCODE_USE { int howMany = 25; uint i, j; printf("\nOpcode use:\n"); for (j = 1; howMany > 0; howMany--, j++) { uint maxUse = 0; uint maxIndex = 0; for (i = 0; i < JitOps.JIT_OPCODE_MAXNUM; i++) { if (opcodeNumUses[i] > maxUse) { maxUse = opcodeNumUses[i]; maxIndex = i; } } printf("%02d 0x%03x: %d\n", j, maxIndex, maxUse); opcodeNumUses[maxIndex] = 0; } } #endif //Sys.Crash("FINISHED!!!"); return(retValue); }
public static tMetaData *GetMetaDataForAssembly(byte *pAssemblyName) { tFilesLoaded *pFiles; int monoAssembly = 0; tCLIFile * pCLIFile = null; tMD_Assembly *pThisAssembly = null; tMetaData ** ppChildMetaData = null; int i, j, childCount; // Check corlib assemblies i = 0; while (dnaCorlibAssemblies[i] != null) { if (S.strcmp(pAssemblyName, dnaCorlibAssemblies[i]) == 0) { pAssemblyName = scCorLib; break; } i++; } // Look in already-loaded files first pFiles = pFilesLoaded; while (pFiles != null) { pCLIFile = pFiles->pCLIFile; if (S.strcmp(pAssemblyName, pCLIFile->assemblyName) == 0) { // Found the correct assembly, so return its meta-data return(pCLIFile->pMetaData); } pFiles = pFiles->pNext; } // Mono/Unity assemblies only load metadata, no code if (monoAssemblies != null) { i = 0; while (monoAssemblies[i] != null) { if (S.strcmp(pAssemblyName, monoAssemblies[i]) == 0) { if (i == 0) { // Handle "UnityEngine" assemblies j = 0; childCount = 0; while (unityModuleAssemblies[j] != null) { childCount++; j++; } ppChildMetaData = (tMetaData **)Mem.malloc((SIZE_T)((childCount + 1) * sizeof(tMetaData *))); Mem.memset(ppChildMetaData, 0, (SIZE_T)((childCount + 1) * sizeof(tMetaData *))); j = 0; while (unityModuleAssemblies[j] != null) { ppChildMetaData[j] = GetMetaDataForAssembly(unityModuleAssemblies[j]); j++; } } monoAssembly = 1; break; } i++; } } // Assembly not loaded, so load it if possible if (monoAssembly != 0) { pCLIFile = CLIFile.WrapMonoAssembly(pAssemblyName); if (pCLIFile == null) { Sys.Crash("Cannot load required mono assembly file: %s.dll", (PTR)pAssemblyName); } } else { byte *fileName = stackalloc byte[256]; S.snprintf(fileName, 256, "%s.dll", (PTR)pAssemblyName); pCLIFile = CLIFile.LoadAssembly(fileName); if (pCLIFile == null) { Sys.Crash("Cannot load required assembly file: %s.dll", (PTR)pAssemblyName); } } pCLIFile->pMetaData->ppChildMetaData = ppChildMetaData; return(pCLIFile->pMetaData); }