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(); } }
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; } }
public ISymbolNode ComputeConstantLookup(ReadyToRunHelperId helperId, object entity, SignatureContext signatureContext) { return(_compilation.SymbolNodeFactory.ReadyToRunHelper(helperId, entity, signatureContext)); }
public ReadyToRunHelperKey(ReadyToRunHelperId helperId, object target) { HelperId = helperId; Target = target; }
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) { }
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)); }
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); }
public ISymbolNode ReadyToRunHelper(ReadyToRunHelperId id, Object target) { return(_readyToRunHelpers.GetOrAdd(new Tuple <ReadyToRunHelperId, object>(id, target))); }
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); } }
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)); }
public ISymbolNode ReadyToRunHelper(ReadyToRunHelperId id, Object target) { throw new NotImplementedException(); }
public ISymbolNode ReadyToRunHelperFromTypeLookup(ReadyToRunHelperId id, Object target, TypeSystemEntity dictionaryOwner) { throw new NotImplementedException(); }
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(); }
public ISymbolNode ReadyToRunHelperFromDictionaryLookup(ReadyToRunHelperId id, Object target, TypeSystemEntity dictionaryOwner) { return(_genericReadyToRunHelpersFromDict.GetOrAdd(new Tuple <ReadyToRunHelperId, object, TypeSystemEntity>(id, target, dictionaryOwner))); }
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(); }
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); }
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); }
public ReadyToRunHelperKey(ReadyToRunHelperId id, object target) { Id = id; Target = target; }
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; }
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; } }
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)); }
public ReadyToRunHelperKey(ReadyToRunHelperId id, Object obj) { _id = id; _obj = obj; }
public ReadyToRunHelperKey(ReadyToRunHelperId id, object target, SignatureContext signatureContext) { Id = id; Target = target; SignatureContext = signatureContext; }
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); }
public ISymbolNode ReadyToRunHelper(ReadyToRunHelperId id, object target, SignatureContext signatureContext) { return(_r2rHelpers.GetOrAdd(new ReadyToRunHelperKey(id, target, signatureContext))); }
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()); } }
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); }