private void ScheduleMethods(MosaType type) { var currentType = type; var slots = new bool[TypeLayout.GetMethodTable(type).Count]; while (currentType != null) { foreach (var method in currentType.Methods) { bool contains; lock (invokedMethods) { contains = invokedMethods.Contains(method); } if (contains) { int slot = TypeLayout.GetMethodSlot(method); if (slots[slot]) { continue; } slots[slot] = true; ScheduleMethod(method); } } currentType = currentType.BaseType; // EXPLORE: base types may not need to be considered } }
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); } } }
private uint CalculateInterfaceMethodTableOffset(MosaMethod invokeTarget) { var slot = (uint)TypeLayout.GetMethodSlot(invokeTarget); // Skip the first two entries (TypeDef and Count) slot += 2; return(NativePointerSize * 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); } } }
private int CalculateMethodTableOffset(MosaMethod invokeTarget) { int slot = TypeLayout.GetMethodSlot(invokeTarget); return(NativePointerSize * slot); }
private uint CalculateMethodTableOffset(MosaMethod invokeTarget) { var slot = (uint)TypeLayout.GetMethodSlot(invokeTarget); return(NativePointerSize * (slot + 14)); // 14 is the offset into the TypeDef to the start of the MethodTable }