public void InterfaceMethodInvoked(MosaMethod method, MosaMethod source) { 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) { 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 void Phi(InstructionNode node) { //if (Trace.Active) Trace.Log(node.ToString()); var result = GetVariableState(node.Result); if (result.IsOverDefined) { return; } var sourceBlocks = node.PhiBlocks; var currentBlock = node.Block; //if (Trace.Active) Trace.Log("Loop: " + currentBlock.PreviousBlocks.Count.ToString()); for (var index = 0; index < currentBlock.PreviousBlocks.Count; index++) { var predecessor = sourceBlocks[index]; phiStatements.AddIfNew(predecessor, node); bool executable = blockStates[predecessor.Sequence]; //if (Trace.Active) Trace.Log("# " + index.ToString() + ": " + predecessor.ToString() + " " + (executable ? "Yes" : "No")); if (!executable) { continue; } if (result.IsOverDefined) { continue; } var op = node.GetOperand(index); var operand = GetVariableState(op); //if (Trace.Active) Trace.Log("# " + index.ToString() + ": " + operand.ToString()); CheckAndUpdateNullAssignment(result, operand); if (operand.IsOverDefined) { UpdateToOverDefined(result); continue; } else if (operand.IsSingleConstant) { UpdateToConstant(result, operand.ConstantUnsignedLongInteger); continue; } else if (operand.HasMultipleConstants) { foreach (var c in operand.Constants) { UpdateToConstant(result, c); if (result.IsOverDefined) { break; } } } } }