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 ISymbolNode GetGenericLookupHelper(ReadyToRunHelperId helperId, object helperArgument) { GenericDictionaryLookup lookup = _compilation.ComputeGenericLookup(_canonMethod, helperId, helperArgument); Debug.Assert(lookup.UseHelper); if (_canonMethod.RequiresInstMethodDescArg()) { return(_compilation.NodeFactory.ReadyToRunHelperFromDictionaryLookup(lookup.HelperId, lookup.HelperObject, _canonMethod)); } else { Debug.Assert(_canonMethod.RequiresInstArg() || _canonMethod.AcquiresInstMethodTableFromThis()); return(_compilation.NodeFactory.ReadyToRunHelperFromTypeLookup(lookup.HelperId, lookup.HelperObject, _canonMethod.OwningType)); } }