public ReadyToRunGenericHelperNode(NodeFactory factory, ReadyToRunHelperId helperId, object target, TypeSystemEntity dictionaryOwner)
        {
            _id = helperId;
            _dictionaryOwner = dictionaryOwner;
            _target = target;

            _lookupSignature = GetLookupSignature(factory, helperId, target);
        }
 private static GenericLookupResult GetLookupSignature(NodeFactory factory, ReadyToRunHelperId id, object target)
 {
     switch (id)
     {
         case ReadyToRunHelperId.TypeHandle:
             return factory.GenericLookup.Type((TypeDesc)target);
         case ReadyToRunHelperId.GetGCStaticBase:
             return factory.GenericLookup.TypeGCStaticBase((TypeDesc)target);
         case ReadyToRunHelperId.GetNonGCStaticBase:
             return factory.GenericLookup.TypeNonGCStaticBase((TypeDesc)target);
         case ReadyToRunHelperId.MethodDictionary:
             return factory.GenericLookup.MethodDictionary((MethodDesc)target);
         case ReadyToRunHelperId.VirtualCall:
             return factory.GenericLookup.VirtualCall((MethodDesc)target);
         case ReadyToRunHelperId.MethodEntry:
             return factory.GenericLookup.MethodEntry((MethodDesc)target);
         default:
             throw new NotImplementedException();
     }
 }
예제 #3
0
        public ReadyToRunHelperNode(NodeFactory factory, ReadyToRunHelperId id, Object target)
        {
            _id = id;
            _target = target;

            switch (id)
            {
                case ReadyToRunHelperId.NewHelper:
                case ReadyToRunHelperId.NewArr1:
                    {
                        // Make sure that if the EEType can't be generated, we throw the exception now.
                        // This way we can fail generating code for the method that references the EEType
                        // and (depending on the policy), we could avoid scraping the entire compilation.
                        TypeDesc type = (TypeDesc)target;
                        factory.ConstructedTypeSymbol(type);
                    }
                    break;
                case ReadyToRunHelperId.IsInstanceOf:
                case ReadyToRunHelperId.CastClass:
                    {
                        // Make sure that if the EEType can't be generated, we throw the exception now.
                        // This way we can fail generating code for the method that references the EEType
                        // and (depending on the policy), we could avoid scraping the entire compilation.
                        TypeDesc type = (TypeDesc)target;
                        factory.NecessaryTypeSymbol(type);

                        Debug.Assert(!type.IsNullable, "Nullable needs to be unwrapped");
                    }
                    break;
                case ReadyToRunHelperId.GetNonGCStaticBase:
                case ReadyToRunHelperId.GetGCStaticBase:
                case ReadyToRunHelperId.GetThreadStaticBase:
                    {
                        // Make sure we can compute static field layout now so we can fail early
                        DefType defType = (DefType)target;
                        defType.ComputeStaticFieldLayout(StaticLayoutKind.StaticRegionSizesAndFields);
                    }
                    break;
            }
        }
예제 #4
0
 public ISymbolNode ComputeConstantLookup(ReadyToRunHelperId helperId, object entity, SignatureContext signatureContext)
 {
     return(_compilation.SymbolNodeFactory.ReadyToRunHelper(helperId, entity, signatureContext));
 }
예제 #5
0
 public ReadyToRunHelperKey(ReadyToRunHelperId helperId, object target)
 {
     HelperId = helperId;
     Target   = target;
 }
예제 #6
0
 public ReadyToRunHelperNode(ReadyToRunHelperId id, Object target)
 {
     _id     = id;
     _target = target;
 }
 public ISymbolNode ReadyToRunHelperFromTypeLookup(ReadyToRunHelperId id, Object target, TypeSystemEntity dictionaryOwner)
 {
     return(_genericReadyToRunHelpersFromType.GetOrAdd(new ReadyToRunGenericHelperKey(id, target, dictionaryOwner)));
 }
 public WebAssemblyReadyToRunGenericLookupFromTypeNode(NodeFactory factory, ReadyToRunHelperId helperId, object target, TypeSystemEntity dictionaryOwner)
     : base(factory, helperId, target, dictionaryOwner)
 {
 }
예제 #9
0
        public GenericDictionaryLookup ComputeGenericLookup(MethodDesc contextMethod, ReadyToRunHelperId lookupKind, object targetOfLookup)
        {
            GenericContextSource contextSource;

            if (contextMethod.RequiresInstMethodDescArg())
            {
                contextSource = GenericContextSource.MethodParameter;
            }
            else if (contextMethod.RequiresInstMethodTableArg())
            {
                contextSource = GenericContextSource.TypeParameter;
            }
            else
            {
                Debug.Assert(contextMethod.AcquiresInstMethodTableFromThis());
                contextSource = GenericContextSource.ThisObject;
            }

            // Can we do a fixed lookup? Start by checking if we can get to the dictionary.
            // Context source having a vtable with fixed slots is a prerequisite.
            if (contextSource == GenericContextSource.MethodParameter ||
                HasFixedSlotVTable(contextMethod.OwningType))
            {
                DictionaryLayoutNode dictionaryLayout;
                if (contextSource == GenericContextSource.MethodParameter)
                {
                    dictionaryLayout = _nodeFactory.GenericDictionaryLayout(contextMethod);
                }
                else
                {
                    dictionaryLayout = _nodeFactory.GenericDictionaryLayout(contextMethod.OwningType);
                }

                // If the dictionary layout has fixed slots, we can compute the lookup now. Otherwise defer to helper.
                if (dictionaryLayout.HasFixedSlots)
                {
                    int pointerSize = _nodeFactory.Target.PointerSize;

                    GenericLookupResult lookup = ReadyToRunGenericHelperNode.GetLookupSignature(_nodeFactory, lookupKind, targetOfLookup);
                    int dictionarySlot         = dictionaryLayout.GetSlotForEntry(lookup);
                    int dictionaryOffset       = dictionarySlot * pointerSize;

                    if (contextSource == GenericContextSource.MethodParameter)
                    {
                        return(GenericDictionaryLookup.CreateFixedLookup(contextSource, dictionaryOffset));
                    }
                    else
                    {
                        int vtableSlot   = VirtualMethodSlotHelper.GetGenericDictionarySlot(_nodeFactory, contextMethod.OwningType);
                        int vtableOffset = EETypeNode.GetVTableOffset(pointerSize) + vtableSlot * pointerSize;
                        return(GenericDictionaryLookup.CreateFixedLookup(contextSource, vtableOffset, dictionaryOffset));
                    }
                }
            }

            // Fixed lookup not possible - use helper.
            return(GenericDictionaryLookup.CreateHelperLookup(contextSource));
        }
예제 #10
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;
                }

                // Necessary type handle is not something that can be in a dictionary (only a constructed type).
                // We only use necessary type handles if we can do a constant lookup.
                if (helperId == ReadyToRunHelperId.NecessaryTypeHandle)
                {
                    helperId = ReadyToRunHelperId.TypeHandle;
                }

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

                if (genericLookup.UseHelper)
                {
                    lookup.runtimeLookup.indirections    = CORINFO.USEHELPER;
                    lookup.lookupKind.runtimeLookupFlags = (ushort)helperId;
                    lookup.lookupKind.runtimeLookupArgs  = (void *)ObjectToHandle(entity);
                }
                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.ComputeConstantLookup(helperId, entity);
                lookup.constLookup = CreateConstLookupToSymbol(constLookup);
            }
        }
        private ILCompiler.DependencyAnalysis.ReadyToRun.ReadyToRunHelper GetGenericStaticHelper(ReadyToRunHelperId helperId)
        {
            ILCompiler.DependencyAnalysis.ReadyToRun.ReadyToRunHelper r2rHelper;

            switch (helperId)
            {
            case ReadyToRunHelperId.GetGCStaticBase:
                r2rHelper = ILCompiler.DependencyAnalysis.ReadyToRun.ReadyToRunHelper.READYTORUN_HELPER_GenericGcStaticBase;
                break;

            case ReadyToRunHelperId.GetNonGCStaticBase:
                r2rHelper = ILCompiler.DependencyAnalysis.ReadyToRun.ReadyToRunHelper.READYTORUN_HELPER_GenericNonGcStaticBase;
                break;

            case ReadyToRunHelperId.GetThreadStaticBase:
                r2rHelper = ILCompiler.DependencyAnalysis.ReadyToRun.ReadyToRunHelper.READYTORUN_HELPER_GenericGcTlsBase;
                break;

            case ReadyToRunHelperId.GetThreadNonGcStaticBase:
                r2rHelper = ILCompiler.DependencyAnalysis.ReadyToRun.ReadyToRunHelper.READYTORUN_HELPER_GenericNonGcTlsBase;
                break;

            default:
                throw new NotImplementedException();
            }

            return(r2rHelper);
        }
예제 #12
0
 public ISymbolNode ReadyToRunHelper(ReadyToRunHelperId id, Object target)
 {
     return(_readyToRunHelpers.GetOrAdd(new Tuple <ReadyToRunHelperId, object>(id, target)));
 }
예제 #13
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);
            }
        }
예제 #14
0
        private bool getReadyToRunHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken, ref CORINFO_LOOKUP_KIND pGenericLookupKind, CorInfoHelpFunc id, ref CORINFO_CONST_LOOKUP pLookup)
        {
            switch (id)
            {
            case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_NEW:
            {
                var type = HandleToObject(pResolvedToken.hClass);
                Debug.Assert(type.IsDefType);
                if (type.IsCanonicalSubtype(CanonicalFormKind.Any))
                {
                    return(false);
                }

                pLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.ReadyToRunHelper(ReadyToRunHelperId.NewHelper, type, _signatureContext));
            }
            break;

            case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_NEWARR_1:
            {
                var type = HandleToObject(pResolvedToken.hClass);
                Debug.Assert(type.IsSzArray);
                if (type.IsCanonicalSubtype(CanonicalFormKind.Any))
                {
                    return(false);
                }

                pLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.ReadyToRunHelper(ReadyToRunHelperId.NewArr1, type, _signatureContext));
            }
            break;

            case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_ISINSTANCEOF:
            {
                var type = HandleToObject(pResolvedToken.hClass);
                if (type.IsCanonicalSubtype(CanonicalFormKind.Any))
                {
                    return(false);
                }

                // ECMA-335 III.4.3:  If typeTok is a nullable type, Nullable<T>, it is interpreted as "boxed" T
                if (type.IsNullable)
                {
                    type = type.Instantiation[0];
                }

                pLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.ReadyToRunHelper(ReadyToRunHelperId.IsInstanceOf, type, _signatureContext));
            }
            break;

            case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_CHKCAST:
            {
                var type = HandleToObject(pResolvedToken.hClass);
                if (type.IsCanonicalSubtype(CanonicalFormKind.Any))
                {
                    return(false);
                }

                // ECMA-335 III.4.3:  If typeTok is a nullable type, Nullable<T>, it is interpreted as "boxed" T
                if (type.IsNullable)
                {
                    type = type.Instantiation[0];
                }

                pLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.ReadyToRunHelper(ReadyToRunHelperId.CastClass, type, _signatureContext));
            }
            break;

            case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_STATIC_BASE:
            {
                var type = HandleToObject(pResolvedToken.hClass);
                if (type.IsCanonicalSubtype(CanonicalFormKind.Any))
                {
                    return(false);
                }

                pLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.ReadyToRunHelper(ReadyToRunHelperId.CctorTrigger, type, _signatureContext));
            }
            break;

            case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_GENERIC_HANDLE:
            {
                Debug.Assert(pGenericLookupKind.needsRuntimeLookup);

                ReadyToRunHelperId helperId  = (ReadyToRunHelperId)pGenericLookupKind.runtimeLookupFlags;
                object             helperArg = HandleToObject((IntPtr)pGenericLookupKind.runtimeLookupArgs);
                if (helperArg is MethodDesc methodArg)
                {
                    helperArg = new MethodWithToken(methodArg, new ModuleToken(_tokenContext, pResolvedToken.token));
                }
                GenericContext methodContext = new GenericContext(entityFromContext(pResolvedToken.tokenContext));
                ISymbolNode    helper        = _compilation.SymbolNodeFactory.GenericLookupHelper(
                    pGenericLookupKind.runtimeLookupKind,
                    helperId,
                    helperArg,
                    methodContext,
                    _signatureContext);
                pLookup = CreateConstLookupToSymbol(helper);
            }
            break;

            default:
                throw new NotImplementedException("ReadyToRun: " + id.ToString());
            }
            return(true);
        }
 public static GenericDictionaryLookup CreateHelperLookup(GenericContextSource contextSource, ReadyToRunHelperId helperId, object helperObject)
 {
     return(new GenericDictionaryLookup(contextSource, UseHelperOffset, checked ((short)helperId), helperObject));
 }
예제 #16
0
 public ISymbolNode ReadyToRunHelper(ReadyToRunHelperId id, Object target)
 {
     throw new NotImplementedException();
 }
예제 #17
0
 public ISymbolNode ReadyToRunHelperFromTypeLookup(ReadyToRunHelperId id, Object target, TypeSystemEntity dictionaryOwner)
 {
     throw new NotImplementedException();
 }
예제 #18
0
 public ISymbolNode ComputeConstantLookup(ReadyToRunHelperId lookupKind, object targetOfLookup)
 {
     // The current plan seem to be to copy paste from ILCompiler.Compilation, but that's not a sustainable plan
     throw new NotImplementedException();
 }
예제 #19
0
 public ISymbolNode ReadyToRunHelperFromDictionaryLookup(ReadyToRunHelperId id, Object target, TypeSystemEntity dictionaryOwner)
 {
     return(_genericReadyToRunHelpersFromDict.GetOrAdd(new Tuple <ReadyToRunHelperId, object, TypeSystemEntity>(id, target, dictionaryOwner)));
 }
예제 #20
0
 public GenericDictionaryLookup ComputeGenericLookup(MethodDesc contextMethod, ReadyToRunHelperId lookupKind, object targetOfLookup)
 {
     // The current plan seem to be to copy paste from ILCompiler.Compilation, but that's not a sustainable plan
     throw new NotImplementedException();
 }
예제 #21
0
        public ISymbolNode ReadyToRunHelper(ReadyToRunHelperId id, object target, SignatureContext signatureContext)
        {
            if (!_r2rHelpers.TryGetValue(id, out Dictionary <object, ISymbolNode> helperNodeMap))
            {
                helperNodeMap = new Dictionary <object, ISymbolNode>();
                _r2rHelpers.Add(id, helperNodeMap);
            }

            if (helperNodeMap.TryGetValue(target, out ISymbolNode helperNode))
            {
                return(helperNode);
            }

            switch (id)
            {
            case ReadyToRunHelperId.NewHelper:
                helperNode = CreateNewHelper((TypeDesc)target, signatureContext);
                break;

            case ReadyToRunHelperId.NewArr1:
                helperNode = CreateNewArrayHelper((ArrayType)target, signatureContext);
                break;

            case ReadyToRunHelperId.GetGCStaticBase:
                helperNode = CreateGCStaticBaseHelper((TypeDesc)target, signatureContext);
                break;

            case ReadyToRunHelperId.GetNonGCStaticBase:
                helperNode = CreateNonGCStaticBaseHelper((TypeDesc)target, signatureContext);
                break;

            case ReadyToRunHelperId.GetThreadStaticBase:
                helperNode = CreateThreadGcStaticBaseHelper((TypeDesc)target, signatureContext);
                break;

            case ReadyToRunHelperId.GetThreadNonGcStaticBase:
                helperNode = CreateThreadNonGcStaticBaseHelper((TypeDesc)target, signatureContext);
                break;

            case ReadyToRunHelperId.IsInstanceOf:
                helperNode = CreateIsInstanceOfHelper((TypeDesc)target, signatureContext);
                break;

            case ReadyToRunHelperId.CastClass:
                helperNode = CreateCastClassHelper((TypeDesc)target, signatureContext);
                break;

            case ReadyToRunHelperId.TypeHandle:
                helperNode = CreateTypeHandleHelper((TypeDesc)target, signatureContext);
                break;

            case ReadyToRunHelperId.FieldHandle:
                helperNode = CreateFieldHandleHelper((FieldDesc)target, signatureContext);
                break;

            case ReadyToRunHelperId.VirtualCall:
                helperNode = CreateVirtualCallHelper((MethodWithToken)target, signatureContext);
                break;

            case ReadyToRunHelperId.DelegateCtor:
                helperNode = CreateDelegateCtorHelper((DelegateCreationInfo)target, signatureContext);
                break;

            default:
                throw new NotImplementedException();
            }

            helperNodeMap.Add(target, helperNode);
            return(helperNode);
        }
예제 #22
0
        private bool getReadyToRunHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken, ref CORINFO_LOOKUP_KIND pGenericLookupKind, CorInfoHelpFunc id, ref CORINFO_CONST_LOOKUP pLookup)
        {
            switch (id)
            {
            case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_NEW:
            {
                var type = HandleToObject(pResolvedToken.hClass);
                Debug.Assert(type.IsDefType);
                if (type.IsCanonicalSubtype(CanonicalFormKind.Any))
                {
                    return(false);
                }

                pLookup = CreateConstLookupToSymbol(_compilation.NodeFactory.ReadyToRunHelper(ReadyToRunHelperId.NewHelper, type));
            }
            break;

            case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_NEWARR_1:
            {
                var type = HandleToObject(pResolvedToken.hClass);
                Debug.Assert(type.IsSzArray);
                if (type.IsCanonicalSubtype(CanonicalFormKind.Any))
                {
                    return(false);
                }

                pLookup = CreateConstLookupToSymbol(_compilation.NodeFactory.ReadyToRunHelper(ReadyToRunHelperId.NewArr1, type));
            }
            break;

            case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_ISINSTANCEOF:
            {
                var type = HandleToObject(pResolvedToken.hClass);
                if (type.IsCanonicalSubtype(CanonicalFormKind.Any))
                {
                    return(false);
                }

                // ECMA-335 III.4.3:  If typeTok is a nullable type, Nullable<T>, it is interpreted as "boxed" T
                if (type.IsNullable)
                {
                    type = type.Instantiation[0];
                }

                pLookup = CreateConstLookupToSymbol(_compilation.NodeFactory.ReadyToRunHelper(ReadyToRunHelperId.IsInstanceOf, type));
            }
            break;

            case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_CHKCAST:
            {
                var type = HandleToObject(pResolvedToken.hClass);
                if (type.IsCanonicalSubtype(CanonicalFormKind.Any))
                {
                    return(false);
                }

                // ECMA-335 III.4.3:  If typeTok is a nullable type, Nullable<T>, it is interpreted as "boxed" T
                if (type.IsNullable)
                {
                    type = type.Instantiation[0];
                }

                pLookup = CreateConstLookupToSymbol(_compilation.NodeFactory.ReadyToRunHelper(ReadyToRunHelperId.CastClass, type));
            }
            break;

            case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_STATIC_BASE:
            {
                var type = HandleToObject(pResolvedToken.hClass);
                if (type.IsCanonicalSubtype(CanonicalFormKind.Any))
                {
                    return(false);
                }

                pLookup = CreateConstLookupToSymbol(_compilation.NodeFactory.ReadyToRunHelper(ReadyToRunHelperId.GetNonGCStaticBase, type));
            }
            break;

            case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE:
            {
                // Token == 0 means "initialize this class". We only expect RyuJIT to call it for this case.
                Debug.Assert(pResolvedToken.token == 0 && pResolvedToken.tokenScope == null);
                Debug.Assert(pGenericLookupKind.needsRuntimeLookup);

                DefType typeToInitialize = (DefType)MethodBeingCompiled.OwningType;
                Debug.Assert(typeToInitialize.IsCanonicalSubtype(CanonicalFormKind.Any));

                DefType     helperArg = typeToInitialize.ConvertToSharedRuntimeDeterminedForm();
                ISymbolNode helper    = GetGenericLookupHelper(pGenericLookupKind.runtimeLookupKind, ReadyToRunHelperId.GetNonGCStaticBase, helperArg);
                pLookup = CreateConstLookupToSymbol(helper);
            }
            break;

            case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_GENERIC_HANDLE:
            {
                Debug.Assert(pGenericLookupKind.needsRuntimeLookup);

                ReadyToRunHelperId helperId  = (ReadyToRunHelperId)pGenericLookupKind.runtimeLookupFlags;
                object             helperArg = HandleToObject((IntPtr)pGenericLookupKind.runtimeLookupArgs);
                ISymbolNode        helper    = GetGenericLookupHelper(pGenericLookupKind.runtimeLookupKind, helperId, helperArg);
                pLookup = CreateConstLookupToSymbol(helper);
            }
            break;

            default:
                throw new NotImplementedException("ReadyToRun: " + id.ToString());
            }
            return(true);
        }
예제 #23
0
 public ReadyToRunHelperKey(ReadyToRunHelperId id, object target)
 {
     Id     = id;
     Target = target;
 }
예제 #24
0
 public ISymbolNode ReadyToRunHelper(ReadyToRunHelperId id, Object target)
 {
     return(_readyToRunHelpers.GetOrAdd(new ReadyToRunHelperKey(id, target)));
 }
 public ReadyToRunGenericLookupFromTypeNode(NodeFactory factory, ReadyToRunHelperId helperId, object target, TypeSystemEntity dictionaryOwner)
     : base(factory, helperId, target, dictionaryOwner)
 {
 }
 public ReadyToRunGenericHelperKey(ReadyToRunHelperId helperId, object target, TypeSystemEntity dictionaryOwner)
 {
     HelperId        = helperId;
     Target          = target;
     DictionaryOwner = dictionaryOwner;
 }
예제 #27
0
        private object GetTargetForFixup(object resolvedToken, ReadyToRunHelperId helperId)
        {
            switch (helperId)
            {
                case ReadyToRunHelperId.TypeHandle:
                    if (resolvedToken is TypeDesc)
                        return resolvedToken;
                    else if (resolvedToken is MethodDesc)
                        return ((MethodDesc)resolvedToken).OwningType;
                    else
                        return ((FieldDesc)resolvedToken).OwningType;

                default:
                    return resolvedToken;
            }
        }
예제 #28
0
        public GenericDictionaryLookup ComputeGenericLookup(MethodDesc contextMethod, ReadyToRunHelperId lookupKind, object targetOfLookup)
        {
            if (targetOfLookup is TypeSystemEntity typeSystemEntity)
            {
                _nodeFactory.TypeSystemContext.DetectGenericCycles(contextMethod, typeSystemEntity);
            }

            GenericContextSource contextSource;

            if (contextMethod.RequiresInstMethodDescArg())
            {
                contextSource = GenericContextSource.MethodParameter;
            }
            else if (contextMethod.RequiresInstMethodTableArg())
            {
                contextSource = GenericContextSource.TypeParameter;
            }
            else
            {
                Debug.Assert(contextMethod.AcquiresInstMethodTableFromThis());
                contextSource = GenericContextSource.ThisObject;
            }

            //
            // Some helpers represent logical concepts that might not be something that can be looked up in a dictionary
            //

            // Downgrade type handle for casting to a normal type handle if possible
            if (lookupKind == ReadyToRunHelperId.TypeHandleForCasting)
            {
                var type = (TypeDesc)targetOfLookup;
                if (!type.IsRuntimeDeterminedType ||
                    (!((RuntimeDeterminedType)type).CanonicalType.IsCanonicalDefinitionType(CanonicalFormKind.Universal) &&
                     !((RuntimeDeterminedType)type).CanonicalType.IsNullable))
                {
                    if (type.IsNullable)
                    {
                        targetOfLookup = type.Instantiation[0];
                    }
                    lookupKind = ReadyToRunHelperId.NecessaryTypeHandle;
                }
            }

            // We don't have separate entries for necessary type handles to avoid possible duplication
            if (lookupKind == ReadyToRunHelperId.NecessaryTypeHandle)
            {
                lookupKind = ReadyToRunHelperId.TypeHandle;
            }

            // Can we do a fixed lookup? Start by checking if we can get to the dictionary.
            // Context source having a vtable with fixed slots is a prerequisite.
            if (contextSource == GenericContextSource.MethodParameter ||
                HasFixedSlotVTable(contextMethod.OwningType))
            {
                DictionaryLayoutNode dictionaryLayout;
                if (contextSource == GenericContextSource.MethodParameter)
                {
                    dictionaryLayout = _nodeFactory.GenericDictionaryLayout(contextMethod);
                }
                else
                {
                    dictionaryLayout = _nodeFactory.GenericDictionaryLayout(contextMethod.OwningType);
                }

                // If the dictionary layout has fixed slots, we can compute the lookup now. Otherwise defer to helper.
                if (dictionaryLayout.HasFixedSlots)
                {
                    int pointerSize = _nodeFactory.Target.PointerSize;

                    GenericLookupResult lookup = ReadyToRunGenericHelperNode.GetLookupSignature(_nodeFactory, lookupKind, targetOfLookup);
                    int dictionarySlot         = dictionaryLayout.GetSlotForFixedEntry(lookup);
                    if (dictionarySlot != -1)
                    {
                        int dictionaryOffset = dictionarySlot * pointerSize;

                        bool indirectLastOffset = lookup.LookupResultReferenceType(_nodeFactory) == GenericLookupResultReferenceType.Indirect;

                        if (contextSource == GenericContextSource.MethodParameter)
                        {
                            return(GenericDictionaryLookup.CreateFixedLookup(contextSource, dictionaryOffset, indirectLastOffset: indirectLastOffset));
                        }
                        else
                        {
                            int vtableSlot   = VirtualMethodSlotHelper.GetGenericDictionarySlot(_nodeFactory, contextMethod.OwningType);
                            int vtableOffset = EETypeNode.GetVTableOffset(pointerSize) + vtableSlot * pointerSize;
                            return(GenericDictionaryLookup.CreateFixedLookup(contextSource, vtableOffset, dictionaryOffset, indirectLastOffset: indirectLastOffset));
                        }
                    }
                }
            }

            // Fixed lookup not possible - use helper.
            return(GenericDictionaryLookup.CreateHelperLookup(contextSource, lookupKind, targetOfLookup));
        }
예제 #29
0
 public ReadyToRunHelperKey(ReadyToRunHelperId id, Object obj)
 {
     _id  = id;
     _obj = obj;
 }
예제 #30
0
 public ReadyToRunHelperKey(ReadyToRunHelperId id, object target, SignatureContext signatureContext)
 {
     Id               = id;
     Target           = target;
     SignatureContext = signatureContext;
 }
예제 #31
0
        private ISymbolNode GetGenericLookupHelper(CORINFO_RUNTIME_LOOKUP_KIND runtimeLookupKind, ReadyToRunHelperId helperId, object helperArgument)
        {
            if (runtimeLookupKind == CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_THISOBJ
                || runtimeLookupKind == CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_CLASSPARAM)
            {
                return _compilation.NodeFactory.ReadyToRunHelperFromTypeLookup(helperId, helperArgument, MethodBeingCompiled.OwningType);
            }

            Debug.Assert(runtimeLookupKind == CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_METHODPARAM);
            return _compilation.NodeFactory.ReadyToRunHelperFromDictionaryLookup(helperId, helperArgument, MethodBeingCompiled);
        }
예제 #32
0
 public ISymbolNode ReadyToRunHelper(ReadyToRunHelperId id, object target, SignatureContext signatureContext)
 {
     return(_r2rHelpers.GetOrAdd(new ReadyToRunHelperKey(id, target, signatureContext)));
 }
예제 #33
0
        public ISymbolNode GenericLookupHelper(
            CORINFO_RUNTIME_LOOKUP_KIND runtimeLookupKind,
            ReadyToRunHelperId helperId,
            object helperArgument,
            GenericContext methodContext,
            SignatureContext signatureContext)
        {
            switch (helperId)
            {
            case ReadyToRunHelperId.TypeHandle:
                return(GenericLookupTypeHelper(
                           runtimeLookupKind,
                           ReadyToRunFixupKind.READYTORUN_FIXUP_TypeHandle,
                           helperArgument,
                           methodContext,
                           signatureContext));

            case ReadyToRunHelperId.MethodHandle:
                return(GenericLookupMethodHelper(
                           runtimeLookupKind,
                           ReadyToRunFixupKind.READYTORUN_FIXUP_MethodHandle,
                           (MethodWithToken)helperArgument,
                           methodContext,
                           signatureContext));

            case ReadyToRunHelperId.MethodEntry:
                return(GenericLookupMethodHelper(
                           runtimeLookupKind,
                           ReadyToRunFixupKind.READYTORUN_FIXUP_MethodEntry,
                           (MethodWithToken)helperArgument,
                           methodContext,
                           signatureContext));

            case ReadyToRunHelperId.MethodDictionary:
                return(GenericLookupMethodHelper(
                           runtimeLookupKind,
                           ReadyToRunFixupKind.READYTORUN_FIXUP_MethodHandle,
                           (MethodWithToken)helperArgument,
                           methodContext,
                           signatureContext));

            case ReadyToRunHelperId.TypeDictionary:
                return(GenericLookupTypeHelper(
                           runtimeLookupKind,
                           ReadyToRunFixupKind.READYTORUN_FIXUP_TypeDictionary,
                           (TypeDesc)helperArgument,
                           methodContext,
                           signatureContext));

            case ReadyToRunHelperId.VirtualDispatchCell:
                return(GenericLookupMethodHelper(
                           runtimeLookupKind,
                           ReadyToRunFixupKind.READYTORUN_FIXUP_VirtualEntry,
                           (MethodWithToken)helperArgument,
                           methodContext,
                           signatureContext));

            case ReadyToRunHelperId.FieldHandle:
                return(GenericLookupFieldHelper(
                           runtimeLookupKind,
                           ReadyToRunFixupKind.READYTORUN_FIXUP_FieldHandle,
                           (FieldDesc)helperArgument,
                           methodContext,
                           signatureContext));

            default:
                throw new NotImplementedException(helperId.ToString());
            }
        }
예제 #34
0
 public ReadyToRunHelperNode(ReadyToRunHelperId id, Object target)
 {
     _id = id;
     _target = target;
 }
예제 #35
0
파일: ARMDebug.cs 프로젝트: z77ma/runtime
 public static void EmitHelperNYIAssert(NodeFactory factory, ref ARMEmitter encoder, ReadyToRunHelperId hId,
                                        [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath  = null,
                                        [System.Runtime.CompilerServices.CallerMemberName] string memberName    = null,
                                        [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
 {
     EmitNYIAssert(factory, ref encoder, hId.ToString() + " is not implemented", sourceFilePath, memberName, sourceLineNumber);
 }