Beispiel #1
0
        public override int CompareToImpl(ISortableNode other, CompilerComparer comparer)
        {
            NonExternMethodSymbolNode otherMethod = (NonExternMethodSymbolNode)other;
            var result = _isUnboxing.CompareTo(otherMethod._isUnboxing);

            return(result != 0 ? result : comparer.Compare(_method, otherMethod._method));
        }
        protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
        {
            NonExternMethodSymbolNode otherMethod = (NonExternMethodSymbolNode)other;
            var result = _isUnboxing.CompareTo(otherMethod._isUnboxing);

            return(result != 0 ? result : comparer.Compare(_method, otherMethod._method));
        }
Beispiel #3
0
 public FuncletSymbol(NonExternMethodSymbolNode methodSymbol, int funcletId)
 {
     _funcletId    = funcletId;
     _methodSymbol = methodSymbol;
 }
        //
        // returns the DEBUG_S_FUNC_MDTOKEN_MAP subsection as a byte array
        // DEBUG_S_FUNC_MDTOKEN_MAP subsection contains method RVA to mdToken mapping
        //
        // contents of subsection:
        // offset 0,     4   bytes: count of entries in the map
        // offset 4,     8*N bytes: 4 byte RVA + 4 byte 'offset' relative to the start of 'method data'
        // offset 4+8*N, *   bytes: all method data packed sequentially with no padding. method data consists of
        //                          1 byte 'count' of generic parameters, 3 bytes of method's rid and 'count'
        //                          variable sized ECMA formatted TypeSpec signatures for each generic parameter
        //
        // Compiler places the CTLToken (for a method) or the lexical funclet order (if a method has 1 or more funclets),
        // which binder uses to compute the RVA.
        //
        // all entries are sorted by 'offset' field.
        //
        // 'offset' optimization: if the method has no generic parameters, we don't need to pass in a signature
        //                        and can encode the mdToken of method in 'offset'
        //                        We do this by setting the high bit of 'offset' and then storing rid part of
        //                        token in last 3 bytes of 'offset'
        //
        internal DebugInfoBlob GetDebugMethodRVAToTokenMap(ManagedBinaryEmitter pseudoAssembly, IEnumerable <IMethodBodyNode> emittedMethods, out List <Relocation> debugRelocations)
        {
            DebugInfoBlob methodRVAToTokenMap = new DebugInfoBlob();
            DebugInfoBlob methodDataBlob      = new DebugInfoBlob();

            debugRelocations = new List <Relocation>();
            BlobBuilder blobBuilder = new BlobBuilder();

            uint entryCount = 0;

            methodRVAToTokenMap.WriteDWORD(0); // Placeholder for count of entries in map. Will be udpated later.

            List <EmittedMethodWithILToken> tokenInOffsetEntries = new List <EmittedMethodWithILToken>();

            foreach (IMethodBodyNode emitted in emittedMethods)
            {
                NonExternMethodSymbolNode methodNode = emitted as NonExternMethodSymbolNode;
                if (methodNode != null && !methodNode.HasCompiledBody)
                {
                    continue;
                }

                if (!(emitted.Method.GetTypicalMethodDefinition() is Internal.TypeSystem.Ecma.EcmaMethod))
                {
                    continue;
                }

                EntityHandle methodHandle = pseudoAssembly.EmitMetadataHandleForTypeSystemEntity(emitted.Method.GetTypicalMethodDefinition());
                Debug.Assert(methodHandle.Kind == HandleKind.MemberReference);
                uint methodToken    = (uint)MetadataTokens.GetToken(methodHandle);
                uint methodTokenRid = methodToken & 0xFFFFFF;

                if (!(emitted.Method.HasInstantiation || emitted.Method.OwningType.HasInstantiation))
                {
                    tokenInOffsetEntries.Add(new EmittedMethodWithILToken(emitted, methodTokenRid));
                    continue;
                }

                uint cGenericArguments = checked ((uint)emitted.Method.Instantiation.Length + (uint)emitted.Method.OwningType.Instantiation.Length);

                // Debugger format does not allow the debugging of methods that have more than 255 generic parameters (spread between the type and method instantiation)
                if (cGenericArguments > 0xFF)
                {
                    continue;
                }

                blobBuilder.Clear();

                // write the signature for each generic parameter of class
                foreach (TypeDesc instantiationType in emitted.Method.OwningType.Instantiation)
                {
                    pseudoAssembly.EncodeSignatureForType(instantiationType, blobBuilder);
                }

                // write the signature for each generic parameter of the method
                foreach (TypeDesc instantiationType in emitted.Method.Instantiation)
                {
                    pseudoAssembly.EncodeSignatureForType(instantiationType, blobBuilder);
                }

                Add_DEBUG_S_FUNC_MDTOKEN_MAP_Entry(methodRVAToTokenMap, debugRelocations, emitted, methodDataBlob.Size(), ref entryCount);

                methodDataBlob.WriteDWORD(cGenericArguments << 24 | methodTokenRid);
                methodDataBlob.WriteBuffer(blobBuilder);
            }

            // sort tokenInOffsetEntries based on tokenInOffset
            tokenInOffsetEntries.Sort();

            foreach (EmittedMethodWithILToken emitted in tokenInOffsetEntries)
            {
                Add_DEBUG_S_FUNC_MDTOKEN_MAP_Entry(methodRVAToTokenMap, debugRelocations, emitted.EmittedMethod, emitted.IlTokenRid | 0x80000000, ref entryCount);
            }

            methodRVAToTokenMap.SetDWORDAtBlobIndex(0, entryCount); // // Update placeholder for count of entries in map
            methodRVAToTokenMap.WriteBuffer(methodDataBlob);

            return(methodRVAToTokenMap);
        }