public static int AddMethod(string key, MethodInfo method) { int index = 0; lock (indexLock) { if (nameToKey.TryGetValue(key, out var i)) { return(i); } index = currentIndex++; if ((index & 0x7f) == 127) { internalArrays.Add(new MethodInfo[0x80]); #if DEBUG ThreadSafeLogger.Message("[Analyzer] Adding new internal array to the MethodInfoCache"); #endif } nameToKey.Add(key, index); } internalArrays[index >> 7][index & 0x7f] = method; return(index); }
// Clear the caches which prevent double patching public static void ClearCaches() { PatchedMeths.Clear(); #if DEBUG ThreadSafeLogger.Message("[Analyzer] Cleaned up the transpiler methods caches"); #endif }
public static void AddEntry(string name, Category category) { Type myType = null; if (types.ContainsKey(name)) { myType = types[name]; } else { myType = DynamicTypeBuilder.CreateType(name, null); types.Add(name, myType); } #if DEBUG ThreadSafeLogger.Message($"Adding entry {name} into the category {category}"); #endif var entry = Entry.Create(name, category, myType, true, true); if (Tab(category).entries.ContainsKey(entry)) { ThreadSafeLogger.Error($"Attempting to re-add entry {name} into the category {category}"); } else { Tab(category).entries.Add(entry, myType); } }
/* CreateType creates a type at runtime which inherits from 'Entry', it creates a type with one field and two methods * Field: 'Active' signifying whether the entry is currently active or not * Ctor: Sets 'Active' to false. * Method: 'GetPatchMethods' given a string, finds a list of methods in a dictionary which represent the methods this type is profiling * they are stored in the `methods` dictionary, and added to in the CreateType method. */ public static Type CreateType(string input, HashSet <MethodInfo> methods) { var name = string.Concat(input.Where(x => char.IsLetter(x) && !char.IsSymbol(x) && !char.IsWhiteSpace(x))); #if DEBUG ThreadSafeLogger.Message($"[Analyzer] Converted the parameter called {input} into {name}, creating type"); #endif ThreadSafeLogger.Message(name); TypeBuilder tb = ModuleBuilder.DefineType(name, staticAtt, typeof(Entry)); FieldBuilder active = tb.DefineField("Active", typeof(bool), FieldAttributes.Public | FieldAttributes.Static); DynamicTypeBuilder.methods.Add(name, methods ?? new HashSet <MethodInfo>()); ConstructorBuilder ivCtor = tb.DefineConstructor(MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, new Type[0]); // default initialise active to false. ILGenerator ctorIL = ivCtor.GetILGenerator(); ctorIL.Emit(OpCodes.Ldc_I4_0); ctorIL.Emit(OpCodes.Stsfld, active); ctorIL.Emit(OpCodes.Ret); CreateProfilePatch(name, tb); return(tb.CreateType()); }
public static void ClearCaches() { PatchedInternals.Clear(); #if DEBUG ThreadSafeLogger.Message("[Analyzer] Cleaned up the internal method caches"); #endif }
private static void Notify(string message) { #if DEBUG ThreadSafeLogger.Error($"[Analyzer] Patching notification: {message}"); #endif #if NDEBUG if (!displayMessages) { return; } ThreadSafeLogger.Message($"[Analyzer] Patching notification: {message}"); #endif }
public static void RemoveEntry(string name) { var entry = EntryByName(name); entry.isPatched = false; entry.SetActive(false); Tab(entry.category).entries.Remove(entry); #if DEBUG ThreadSafeLogger.Message($"Removing entry {name} from the category {entry.category.ToString()}"); #endif }
public static void ClearCache() { lock (indexLock) { currentIndex = 0; internalArrays.Clear(); nameToKey.Clear(); } internalArrays.Add(new MethodInfo[0x80]); #if DEBUG ThreadSafeLogger.Message("[Analyzer] Cleaned up the MethodInfoCache"); #endif }
public static void ClearPatchCaches() { patchedAssemblies.Clear(); patchedTypes.Clear(); patchedMethods.Clear(); InternalMethodUtility.ClearCaches(); MethodTransplanting.ClearCaches(); TranspilerMethodUtility.ClearCaches(); MethodInfoCache.ClearCache(); #if DEBUG ThreadSafeLogger.Message("[Analyzer] Cleared all caches"); #endif }