Пример #1
0
        private void ComputeLookup(ref CORINFO_RESOLVED_TOKEN pResolvedToken, object entity, ReadyToRunHelperId helperId, ref CORINFO_LOOKUP lookup)
        {
            if (_compilation.NeedsRuntimeLookup(helperId, entity))
            {
                lookup.lookupKind.needsRuntimeLookup = true;
                lookup.runtimeLookup.signature       = null;

                MethodDesc contextMethod = methodFromContext(pResolvedToken.tokenContext);

                // Do not bother computing the runtime lookup if we are inlining. The JIT is going
                // to abort the inlining attempt anyway.
                if (contextMethod != MethodBeingCompiled)
                {
                    return;
                }

                GenericDictionaryLookup genericLookup = _compilation.ComputeGenericLookup(contextMethod, helperId, entity);

                if (genericLookup.UseHelper)
                {
                    lookup.runtimeLookup.indirections    = CORINFO.USEHELPER;
                    lookup.lookupKind.runtimeLookupFlags = (ushort)genericLookup.HelperId;
                    lookup.lookupKind.runtimeLookupArgs  = (void *)ObjectToHandle(genericLookup.HelperObject);
                }
                else
                {
                    if (genericLookup.ContextSource == GenericContextSource.MethodParameter)
                    {
                        lookup.runtimeLookup.helper = CorInfoHelpFunc.CORINFO_HELP_RUNTIMEHANDLE_METHOD;
                    }
                    else
                    {
                        lookup.runtimeLookup.helper = CorInfoHelpFunc.CORINFO_HELP_RUNTIMEHANDLE_CLASS;
                    }

                    lookup.runtimeLookup.indirections = (ushort)genericLookup.NumberOfIndirections;
                    lookup.runtimeLookup.offset0      = (IntPtr)genericLookup[0];
                    if (genericLookup.NumberOfIndirections > 1)
                    {
                        lookup.runtimeLookup.offset1 = (IntPtr)genericLookup[1];
                    }
                    lookup.runtimeLookup.testForFixup         = false; // TODO: this will be needed in true multifile
                    lookup.runtimeLookup.testForNull          = false;
                    lookup.runtimeLookup.indirectFirstOffset  = false;
                    lookup.runtimeLookup.indirectSecondOffset = false;
                    lookup.lookupKind.runtimeLookupFlags      = 0;
                    lookup.lookupKind.runtimeLookupArgs       = null;
                }

                lookup.lookupKind.runtimeLookupKind = GetLookupKindFromContextSource(genericLookup.ContextSource);
            }
            else
            {
                lookup.lookupKind.needsRuntimeLookup = false;
                ISymbolNode constLookup = _compilation.SymbolNodeFactory.ComputeConstantLookup(helperId, entity, _signatureContext);
                lookup.constLookup = CreateConstLookupToSymbol(constLookup);
            }
        }
Пример #2
0
        private void ComputeLookup(ref CORINFO_RESOLVED_TOKEN pResolvedToken, object entity, ReadyToRunHelperId helperId, ref CORINFO_LOOKUP lookup)
        {
            if (_compilation.NeedsRuntimeLookup(helperId, entity))
            {
                lookup.lookupKind.needsRuntimeLookup = true;

                lookup.runtimeLookup.signature = null;

                MethodDesc contextMethod = methodFromContext(pResolvedToken.tokenContext);

                // Do not bother computing the runtime lookup if we are inlining. The JIT is going
                // to abort the inlining attempt anyway.
                if (contextMethod != _methodCodeNode.Method)
                {
                    return;
                }

                // There is a pathological case where invalid IL refereces __Canon type directly, but there is no dictionary available to store the lookup.
                // All callers of ComputeRuntimeLookupForSharedGenericToken have to filter out this case. We can't do much about it here.
                Debug.Assert(contextMethod.IsSharedByGenericInstantiations);

                if (contextMethod.RequiresInstMethodDescArg())
                {
                    lookup.lookupKind.runtimeLookupKind = CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_METHODPARAM;
                }
                else
                {
                    if (contextMethod.RequiresInstMethodTableArg())
                    {
                        lookup.lookupKind.runtimeLookupKind = CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_CLASSPARAM;
                    }
                    else
                    {
                        lookup.lookupKind.runtimeLookupKind = CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_THISOBJ;
                    }
                }

                // Unless we decide otherwise, just do the lookup via a helper function
                lookup.runtimeLookup.indirections = CORINFO.USEHELPER;

                lookup.lookupKind.runtimeLookupFlags = (ushort)helperId;
                lookup.lookupKind.runtimeLookupArgs  = (void *)ObjectToHandle(entity);

                lookup.runtimeLookup.indirectFirstOffset  = false;
                lookup.runtimeLookup.indirectSecondOffset = false;

                // For R2R compilations, we don't generate the dictionary lookup signatures (dictionary lookups are done in a
                // different way that is more version resilient... plus we can't have pointers to existing MTs/MDs in the sigs)
            }
            else
            {
                lookup.lookupKind.needsRuntimeLookup = false;
                ISymbolNode constLookup = _compilation.SymbolNodeFactory.ComputeConstantLookup(helperId, entity, _signatureContext);
                lookup.constLookup = CreateConstLookupToSymbol(constLookup);
            }
        }