Beispiel #1
0
        public static void EncodePgoData <TType>(IEnumerable <PgoSchemaElem> schemas, IPgoEncodedValueEmitter <TType> valueEmitter, bool emitAllElementsUnconditionally)
        {
            PgoSchemaElem prevSchema         = default(PgoSchemaElem);
            TType         prevEmittedType    = default(TType);
            long          prevEmittedIntData = 0;

            foreach (PgoSchemaElem schema in schemas)
            {
                int ilOffsetDiff = schema.ILOffset - prevSchema.ILOffset;
                int OtherDiff    = schema.Other - prevSchema.Other;
                int CountDiff    = schema.Count - prevSchema.Count;
                int TypeDiff     = (int)schema.InstrumentationKind - (int)prevSchema.InstrumentationKind;

                InstrumentationDataProcessingState modifyMask = (InstrumentationDataProcessingState)0;

                if (!emitAllElementsUnconditionally)
                {
                    if (ilOffsetDiff != 0)
                    {
                        modifyMask = modifyMask | InstrumentationDataProcessingState.ILOffset;
                    }
                    if (TypeDiff != 0)
                    {
                        modifyMask = modifyMask | InstrumentationDataProcessingState.Type;
                    }
                    if (CountDiff != 0)
                    {
                        modifyMask = modifyMask | InstrumentationDataProcessingState.Count;
                    }
                    if (OtherDiff != 0)
                    {
                        modifyMask = modifyMask | InstrumentationDataProcessingState.Other;
                    }
                }
                else
                {
                    modifyMask = InstrumentationDataProcessingState.ILOffset |
                                 InstrumentationDataProcessingState.Type |
                                 InstrumentationDataProcessingState.Count |
                                 InstrumentationDataProcessingState.Other;
                }

                Debug.Assert(modifyMask != InstrumentationDataProcessingState.Done);

                valueEmitter.EmitLong((long)modifyMask, 0);

                if ((modifyMask & InstrumentationDataProcessingState.ILOffset) == InstrumentationDataProcessingState.ILOffset)
                {
                    valueEmitter.EmitLong(schema.ILOffset, prevSchema.ILOffset);
                }
                if ((modifyMask & InstrumentationDataProcessingState.Type) == InstrumentationDataProcessingState.Type)
                {
                    valueEmitter.EmitLong((long)schema.InstrumentationKind, (long)prevSchema.InstrumentationKind);
                }
                if ((modifyMask & InstrumentationDataProcessingState.Count) == InstrumentationDataProcessingState.Count)
                {
                    valueEmitter.EmitLong(schema.Count, prevSchema.Count);
                }
                if ((modifyMask & InstrumentationDataProcessingState.Other) == InstrumentationDataProcessingState.Other)
                {
                    valueEmitter.EmitLong(schema.Other, prevSchema.Other);
                }

                for (int i = 0; i < schema.Count; i++)
                {
                    switch (schema.InstrumentationKind & PgoInstrumentationKind.MarshalMask)
                    {
                    case PgoInstrumentationKind.None:
                        break;

                    case PgoInstrumentationKind.FourByte:
                    {
                        long valueToEmit;
                        if (schema.Count == 1)
                        {
                            valueToEmit = schema.DataLong;
                        }
                        else
                        {
                            valueToEmit = ((int[])schema.DataObject)[i];
                        }
                        valueEmitter.EmitLong(valueToEmit, prevEmittedIntData);
                        prevEmittedIntData = valueToEmit;
                        break;
                    }

                    case PgoInstrumentationKind.EightByte:
                    {
                        long valueToEmit;
                        if (schema.Count == 1)
                        {
                            valueToEmit = schema.DataLong;
                        }
                        else
                        {
                            valueToEmit = ((long[])schema.DataObject)[i];
                        }
                        valueEmitter.EmitLong(valueToEmit, prevEmittedIntData);
                        prevEmittedIntData = valueToEmit;
                        break;
                    }

                    case PgoInstrumentationKind.TypeHandle:
                    {
                        TType typeToEmit = ((TType[])schema.DataObject)[i];
                        valueEmitter.EmitType(typeToEmit, prevEmittedType);
                        prevEmittedType = typeToEmit;
                        break;
                    }
                    }
                }

                prevSchema = schema;
            }

            // Emit a "done" schema
            if (!valueEmitter.EmitDone())
            {
                // If EmitDone returns true, no further data needs to be encoded.
                // Otherwise, emit a "Done" schema
                valueEmitter.EmitLong((long)InstrumentationDataProcessingState.Type, 0);
                valueEmitter.EmitLong((long)PgoInstrumentationKind.Done, (long)prevSchema.InstrumentationKind);
            }
        }
Beispiel #2
0
        public static IEnumerable <PgoSchemaElem> ParsePgoData <TType>(IPgoSchemaDataLoader <TType> dataProvider, IEnumerable <long> inputDataStream, bool longsAreCompressed)
        {
            int           dataCountToRead = 0;
            PgoSchemaElem curSchema       = default(PgoSchemaElem);
            InstrumentationDataProcessingState processingState = InstrumentationDataProcessingState.UpdateProcessMaskFlag;
            long lastDataValue = 0;
            long lastTypeValue = 0;

            foreach (long value in inputDataStream)
            {
                if (dataCountToRead > 0)
                {
                    if (curSchema.DataHeldInDataLong)
                    {
                        if (longsAreCompressed)
                        {
                            lastDataValue += value;
                        }
                        else
                        {
                            lastDataValue = value;
                        }
                        curSchema.DataLong = lastDataValue;
                    }
                    else
                    {
                        int dataIndex = curSchema.Count - dataCountToRead;
                        switch (curSchema.InstrumentationKind & PgoInstrumentationKind.MarshalMask)
                        {
                        case PgoInstrumentationKind.FourByte:
                            if (longsAreCompressed)
                            {
                                lastDataValue += value;
                            }
                            else
                            {
                                lastDataValue = value;
                            }
                            ((int[])curSchema.DataObject)[dataIndex] = checked ((int)lastDataValue);
                            break;

                        case PgoInstrumentationKind.EightByte:
                            if (longsAreCompressed)
                            {
                                lastDataValue += value;
                            }
                            else
                            {
                                lastDataValue = value;
                            }
                            ((long[])curSchema.DataObject)[dataIndex] = lastDataValue;
                            break;

                        case PgoInstrumentationKind.TypeHandle:
                            if (longsAreCompressed)
                            {
                                lastTypeValue += value;
                            }
                            else
                            {
                                lastTypeValue = value;
                            }
                            ((TType[])curSchema.DataObject)[dataIndex] = dataProvider.TypeFromLong(lastTypeValue);
                            break;
                        }
                    }
                    dataCountToRead--;
                    if (dataCountToRead == 0)
                    {
                        yield return(curSchema);

                        curSchema.DataLong   = 0;
                        curSchema.DataObject = null;
                    }
                    continue;
                }

                if (processingState == InstrumentationDataProcessingState.UpdateProcessMaskFlag)
                {
                    processingState = (InstrumentationDataProcessingState)value;
                    continue;
                }

                if ((processingState & InstrumentationDataProcessingState.ILOffset) == InstrumentationDataProcessingState.ILOffset)
                {
                    if (longsAreCompressed)
                    {
                        curSchema.ILOffset = checked ((int)(value + (long)curSchema.ILOffset));
                    }
                    else
                    {
                        curSchema.ILOffset = checked ((int)value);
                    }

                    processingState = processingState & ~InstrumentationDataProcessingState.ILOffset;
                }
                else if ((processingState & InstrumentationDataProcessingState.Type) == InstrumentationDataProcessingState.Type)
                {
                    if (longsAreCompressed)
                    {
                        curSchema.InstrumentationKind = (PgoInstrumentationKind)(((int)(curSchema.InstrumentationKind)) + checked ((int)value));
                    }
                    else
                    {
                        curSchema.InstrumentationKind = (PgoInstrumentationKind)value;
                    }

                    processingState = processingState & ~InstrumentationDataProcessingState.Type;
                }
                else if ((processingState & InstrumentationDataProcessingState.Count) == InstrumentationDataProcessingState.Count)
                {
                    if (longsAreCompressed)
                    {
                        curSchema.Count = checked ((int)(value + (long)curSchema.Count));
                    }
                    else
                    {
                        curSchema.Count = checked ((int)value);
                    }
                    processingState = processingState & ~InstrumentationDataProcessingState.Count;
                }
                else if ((processingState & InstrumentationDataProcessingState.Other) == InstrumentationDataProcessingState.Other)
                {
                    if (longsAreCompressed)
                    {
                        curSchema.Other = checked ((int)(value + (long)curSchema.Other));
                    }
                    else
                    {
                        curSchema.Other = checked ((int)value);
                    }
                    processingState = processingState & ~InstrumentationDataProcessingState.Other;
                }

                if (processingState == InstrumentationDataProcessingState.Done)
                {
                    processingState = InstrumentationDataProcessingState.UpdateProcessMaskFlag;

                    if (curSchema.InstrumentationKind == PgoInstrumentationKind.Done)
                    {
                        yield break;
                    }

                    switch (curSchema.InstrumentationKind & PgoInstrumentationKind.MarshalMask)
                    {
                    case PgoInstrumentationKind.None:
                        yield return(curSchema);

                        break;

                    case PgoInstrumentationKind.FourByte:
                        if (curSchema.Count > 1)
                        {
                            curSchema.DataObject = new int[curSchema.Count];
                        }
                        dataCountToRead = curSchema.Count;
                        break;

                    case PgoInstrumentationKind.EightByte:
                        if (curSchema.Count > 1)
                        {
                            curSchema.DataObject = new long[curSchema.Count];
                        }
                        dataCountToRead = curSchema.Count;
                        break;

                    case PgoInstrumentationKind.TypeHandle:
                        curSchema.DataObject = new TType[curSchema.Count];
                        dataCountToRead      = curSchema.Count;
                        break;

                    default:
                        throw new Exception("Unknown Type");
                    }
                }
            }

            throw new Exception("Partial Instrumentation Data");
        }