private void MethodInvoked(MosaMethod method, MosaMethod source, bool direct) { if (!IsEnabled) { return; } lock (invokedMethods) { if (invokedMethods.Contains(method)) { return; } invokedMethods.Add(method); } if (trace != null) { lock (trace) { if ((lastSource == null && source != null) || (lastSource != source)) { trace.Log($"> Method: {(source == null ? "[NONE]" : source.FullName)}"); lastSource = source; } trace.Log($" >> Invoked: {method.FullName}{(method.IsStatic ? " [Static]" : " [Virtual]")}"); } } lock (_lock) { if (method.IsStatic || method.IsConstructor || method.DeclaringType.IsValueType || direct) { ScheduleMethod(method); } else { bool contains; lock (allocatedTypes) { contains = allocatedTypes.Contains(method.DeclaringType); } if (contains) { ScheduleMethod(method); } var slot = TypeLayout.GetMethodSlot(method); ScheduleDerivedMethods(method.DeclaringType, slot); } } }
public void InterfaceMethodInvoked(MosaMethod method, MosaMethod source) { if (!IsEnabled) { return; } MarkMethodInvoked(method); if (trace != null) { lock (trace) { if ((lastSource == null && source != null) || (lastSource != source)) { trace.Log($"> Method: {(source == null ? "[NONE]" : source.FullName)}"); lastSource = source; } trace.Log($" >> Invoked: {method.FullName}{(method.IsStatic ? " [Static]" : " [Virtual]")}"); } } lock (_lock) { invokedInteraceTypes.Add(method.DeclaringType); int slot = TypeLayout.GetMethodSlot(method); var interfaceType = method.DeclaringType; interfaceSlots.AddIfNew(interfaceType, slot); // For every allocated type that implements this interface method, schedule the type's interface method foreach (var type in TypeSystem.AllTypes) { if (type.IsInterface) { continue; } if (!type.Interfaces.Contains(interfaceType)) { continue; } lock (allocatedTypes) { if (!allocatedTypes.Contains(type)) { continue; } } var imethods = TypeLayout.GetInterfaceTable(type, interfaceType); // this can be slow var imethod = imethods[slot]; // schedule this type's interface method implementation ScheduleMethod(imethod); } } }