public override GenericDictionaryCell GetDictionaryCell() { ushort slot; if (!LazyVTableResolver.TryGetInterfaceSlotNumberFromMethod(Method, out slot)) { Environment.FailFast("Unable to get interface slot number for method"); } return(GenericDictionaryCell.CreateInterfaceCallCell(Method.OwningType, slot)); }
private unsafe static void RegularFuncEval(byte *parameterBuffer, uint parameterBufferSize) { TypesAndValues typesAndValues = new TypesAndValues(); uint trash; uint parameterCount; uint parameterValueSize; uint eeTypeCount; ulong eeType; uint offset = 0; NativeReader reader = new NativeReader(parameterBuffer, parameterBufferSize); offset = reader.DecodeUnsigned(offset, out trash); // The VertexSequence always generate a length, I don't really need it. offset = reader.DecodeUnsigned(offset, out parameterCount); typesAndValues.parameterValues = new byte[parameterCount][]; for (int i = 0; i < parameterCount; i++) { offset = reader.DecodeUnsigned(offset, out parameterValueSize); byte[] parameterValue = new byte[parameterValueSize]; for (int j = 0; j < parameterValueSize; j++) { uint parameterByte; offset = reader.DecodeUnsigned(offset, out parameterByte); parameterValue[j] = (byte)parameterByte; } typesAndValues.parameterValues[i] = parameterValue; } offset = reader.DecodeUnsigned(offset, out eeTypeCount); ulong[] debuggerPreparedExternalReferences = new ulong[eeTypeCount]; for (int i = 0; i < eeTypeCount; i++) { offset = reader.DecodeUnsignedLong(offset, out eeType); debuggerPreparedExternalReferences[i] = eeType; } TypeSystemContext typeSystemContext = TypeSystemContextFactory.Create(); bool hasThis; TypeDesc[] parameters; bool[] parametersWithGenericDependentLayout; bool result = TypeLoaderEnvironment.Instance.GetCallingConverterDataFromMethodSignature_NativeLayout_Debugger(typeSystemContext, RuntimeSignature.CreateFromNativeLayoutSignatureForDebugger(offset), Instantiation.Empty, Instantiation.Empty, out hasThis, out parameters, out parametersWithGenericDependentLayout, reader, debuggerPreparedExternalReferences); typesAndValues.types = new RuntimeTypeHandle[parameters.Length]; bool needToDynamicallyLoadTypes = false; for (int i = 0; i < typesAndValues.types.Length; i++) { if (!parameters[i].RetrieveRuntimeTypeHandleIfPossible()) { needToDynamicallyLoadTypes = true; break; } typesAndValues.types[i] = parameters[i].GetRuntimeTypeHandle(); } if (needToDynamicallyLoadTypes) { TypeLoaderEnvironment.Instance.RunUnderTypeLoaderLock(() => { typeSystemContext.FlushTypeBuilderStates(); GenericDictionaryCell[] cells = new GenericDictionaryCell[parameters.Length]; for (int i = 0; i < cells.Length; i++) { cells[i] = GenericDictionaryCell.CreateTypeHandleCell(parameters[i]); } IntPtr[] eetypePointers; TypeBuilder.ResolveMultipleCells(cells, out eetypePointers); for (int i = 0; i < parameters.Length; i++) { typesAndValues.types[i] = ((EEType *)eetypePointers[i])->ToRuntimeTypeHandle(); } }); } TypeSystemContextFactory.Recycle(typeSystemContext); LocalVariableType[] argumentTypes = new LocalVariableType[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { // TODO, FuncEval, what these false really means? Need to make sure our format contains those information argumentTypes[i] = new LocalVariableType(typesAndValues.types[i], false, false); } LocalVariableSet.SetupArbitraryLocalVariableSet <TypesAndValues>(HighLevelDebugFuncEvalHelperWithVariables, ref typesAndValues, argumentTypes); }
public override GenericDictionaryCell GetDictionaryCell() { return(GenericDictionaryCell.CreateExactCallableMethodCell(Method)); }
private bool ResolveGenericVirtualMethodTarget(RuntimeTypeHandle targetTypeHandle, RuntimeTypeHandle declaringTypeHandle, RuntimeTypeHandle[] genericArguments, MethodNameAndSignature callingMethodNameAndSignature, out IntPtr methodPointer, out IntPtr dictionaryPointer) { if (IsPregeneratedOrTemplateRuntimeTypeHandle(targetTypeHandle)) { // If the target type isn't dynamic, or at least is template type generated, the static lookup logic is what we want. return(ResolveGenericVirtualMethodTarget_Static(targetTypeHandle, declaringTypeHandle, genericArguments, callingMethodNameAndSignature, out methodPointer, out dictionaryPointer)); } else { #if SUPPORTS_NATIVE_METADATA_TYPE_LOADING methodPointer = IntPtr.Zero; dictionaryPointer = IntPtr.Zero; TypeSystemContext context = TypeSystemContextFactory.Create(); DefType targetType = (DefType)context.ResolveRuntimeTypeHandle(targetTypeHandle); // Method being called... MethodDesc targetVirtualMethod = ResolveTypeHandleAndMethodNameAndSigToVirtualMethodDesc(context, declaringTypeHandle, callingMethodNameAndSignature); if (targetVirtualMethod == null) { // If we can't find the method in the type system, it must only be present in the static environment. Search there instead. TypeSystemContextFactory.Recycle(context); return(ResolveGenericVirtualMethodTarget_Static(targetTypeHandle, declaringTypeHandle, genericArguments, callingMethodNameAndSignature, out methodPointer, out dictionaryPointer)); } MethodDesc dispatchMethod = targetType.FindVirtualFunctionTargetMethodOnObjectType(targetVirtualMethod); if (dispatchMethod == null) { return(false); } Instantiation targetMethodInstantiation = context.ResolveRuntimeTypeHandles(genericArguments); MethodDesc instantiatedDispatchMethod = dispatchMethod.Context.ResolveGenericMethodInstantiation(dispatchMethod.OwningType.IsValueType /* get the unboxing stub */, dispatchMethod.OwningType.GetClosestDefType(), dispatchMethod.NameAndSignature, targetMethodInstantiation, IntPtr.Zero, false); GenericDictionaryCell cell = GenericDictionaryCell.CreateMethodCell(instantiatedDispatchMethod, false); using (LockHolder.Hold(_typeLoaderLock)) { // Now that we hold the lock, we may find that existing types can now find // their associated RuntimeTypeHandle. Flush the type builder states as a way // to force the reresolution of RuntimeTypeHandles which couldn't be found before. context.FlushTypeBuilderStates(); TypeBuilder.ResolveSingleCell(cell, out methodPointer); } TypeSystemContextFactory.Recycle(context); return(true); #else methodPointer = IntPtr.Zero; dictionaryPointer = IntPtr.Zero; Environment.FailFast("GVM Resolution for non template or pregenerated type"); return(false); #endif } }
public override IntPtr OnEntryPoint(MethodEntrypointPtr methodEntrypoint, IntPtr callerArgs) { lock (this) { if (_corInfoImpl == null) { InitJitCodeManager(RuntimeAugments.RhGetOSModuleForMrt()); // TODO: Recycle jit interface object and TypeSystemContext _context = TypeSystemContextFactory.Create(); Compilation compilation = new Compilation(_context); _nodeFactory = compilation.NodeFactory; JitConfigProvider configProvider = new JitConfigProvider(new CorJitFlag[] { CorJitFlag.CORJIT_FLAG_DEBUG_CODE }, Array.Empty <KeyValuePair <string, string> >()); _corInfoImpl = new CorInfoImpl(compilation, configProvider); } MethodDesc methodToCompile = methodEntrypoint.MethodIdentifier.ToMethodDesc(_context); JitMethodCodeNode codeNode = new JitMethodCodeNode(methodToCompile); _corInfoImpl.CompileMethod(codeNode); ObjectNode.ObjectData codeData = codeNode.GetData(null, false); List <ObjectNode> nodesToEmit = new List <ObjectNode>(); Dictionary <DependencyNodeCore <NodeFactory>, object> relocTargets = new Dictionary <DependencyNodeCore <NodeFactory>, object>(); int totalAllocSizeNeeded = 0; int nonObjectRelocTargets = 0; nodesToEmit.Add(codeNode); UpdateBytesUsed(codeNode.GetData(_nodeFactory), ref totalAllocSizeNeeded); int offsetOfEHData = totalAllocSizeNeeded; if (codeNode.EHInfo != null) { Debug.Assert(codeNode.EHInfo.Alignment == 1); // Assert needed as otherwise offsetOfEHData will be wrong UpdateBytesUsed(codeNode.EHInfo, ref totalAllocSizeNeeded); ComputeDependencySizeAndRelocData(codeNode.EHInfo, relocTargets, nodesToEmit, ref totalAllocSizeNeeded, ref nonObjectRelocTargets); } for (int i = 0; i < nodesToEmit.Count; i++) { ObjectNode objNode = nodesToEmit[i]; ComputeDependencySizeAndRelocData(objNode.GetData(_nodeFactory, true), relocTargets, nodesToEmit, ref totalAllocSizeNeeded, ref nonObjectRelocTargets); } if (nonObjectRelocTargets != 0) { totalAllocSizeNeeded = totalAllocSizeNeeded.AlignUp(IntPtr.Size); } int relocTargetOffsetStart = totalAllocSizeNeeded; DependencyNodeCore <NodeFactory>[] relocTargetsArray = new DependencyNodeCore <NodeFactory> [nonObjectRelocTargets]; { int iRelocTarget = 0; foreach (var relocTarget in relocTargets) { if (!(relocTarget.Key is ObjectNode)) { relocTargetsArray[iRelocTarget] = relocTarget.Key; totalAllocSizeNeeded += IntPtr.Size; iRelocTarget++; } } Debug.Assert(iRelocTarget == nonObjectRelocTargets); } GenericDictionaryCell[] genDictCells = new GenericDictionaryCell[relocTargetsArray.Length]; for (int iRelocTarget = 0; iRelocTarget < relocTargetsArray.Length; iRelocTarget++) { DependencyNodeCore <NodeFactory> relocTarget = relocTargetsArray[iRelocTarget]; GenericDictionaryCell newCell = null; if (relocTarget is ExternObjectSymbolNode) { var externObjectSymbolNode = (ExternObjectSymbolNode)relocTarget; var newMethodCell = externObjectSymbolNode.GetDictionaryCell(); newCell = newMethodCell; } if (newCell == null) { Environment.FailFast("Unknown reloc target type"); } genDictCells[iRelocTarget] = newCell; } IntPtr[] relocTargetsAsIntPtr = null; TypeLoaderEnvironment.Instance.RunUnderTypeLoaderLock( () => { TypeBuilderApi.ResolveMultipleCells(genDictCells, out relocTargetsAsIntPtr); }); // Layout of allocated memory... // ObjectNodes (aligned as appropriate) IntPtr pCodeManager; IntPtr jittedCode = AllocJittedCode(checked ((uint)totalAllocSizeNeeded), 8 /* TODO, alignment calculation */, out pCodeManager); int currentOffset = 0; foreach (var node in nodesToEmit) { ObjectNode.ObjectData objectData = node.GetData(_nodeFactory); EmitAndRelocData(objectData, jittedCode, relocTargetOffsetStart, ref currentOffset, relocTargetsArray, relocTargetsAsIntPtr); // EHInfo doesn't get its own node, but it does get emitted into the stream. if ((node == codeNode) && (codeNode.EHInfo != null)) { Debug.Assert(offsetOfEHData == currentOffset); EmitAndRelocData(codeNode.EHInfo, jittedCode, relocTargetOffsetStart, ref currentOffset, relocTargetsArray, relocTargetsAsIntPtr); } } foreach (IntPtr ptr in relocTargetsAsIntPtr) { currentOffset = currentOffset.AlignUp(IntPtr.Size); Marshal.WriteIntPtr(jittedCode, currentOffset, ptr); currentOffset += IntPtr.Size; } SetEHInfoPtr(pCodeManager, jittedCode, jittedCode + offsetOfEHData); IntPtr mainRuntimeFunction = IntPtr.Zero; for (int i = 0; i < codeNode.FrameInfos.Length; i++) { FrameInfo frame = codeNode.FrameInfos[i]; byte[] frameData = frame.BlobData; byte[] gcInfoData = Array.Empty <byte>(); byte[] gcInfoDataDeref = frameData; if (i == 0) { // For main function, add the gc info to the data gcInfoDataDeref = gcInfoData = codeNode.GCInfo; } IntPtr publishedFunction = PublishRuntimeFunction(pCodeManager, jittedCode, mainRuntimeFunction, checked ((uint)frame.StartOffset), checked ((uint)frame.EndOffset), frameData, checked ((uint)frameData.Length), gcInfoDataDeref, checked ((uint)gcInfoData.Length)); if (i == 0) { mainRuntimeFunction = publishedFunction; } } if (mainRuntimeFunction != IntPtr.Zero) { UpdateRuntimeFunctionTable(pCodeManager); } methodEntrypoint.MethodCode = jittedCode; return(jittedCode); } }
public override GenericDictionaryCell GetDictionaryCell() { return(GenericDictionaryCell.CreateMethodDictionaryCell(Method)); }
public override GenericDictionaryCell GetDictionaryCell() { return(GenericDictionaryCell.CreateIntPtrCell(FrozenStrings.GetRawPointer(FrozenString))); }
private static void HighLevelDebugFuncEvalHelper() { uint parameterBufferSize = RuntimeAugments.RhpGetFuncEvalParameterBufferSize(); IntPtr writeParameterCommandPointer; IntPtr debuggerBufferPointer; unsafe { byte *debuggerBufferRawPointer = stackalloc byte[(int)parameterBufferSize]; debuggerBufferPointer = new IntPtr(debuggerBufferRawPointer); WriteParameterCommand writeParameterCommand = new WriteParameterCommand { commandCode = 1, bufferAddress = debuggerBufferPointer.ToInt64() }; writeParameterCommandPointer = new IntPtr(&writeParameterCommand); RuntimeAugments.RhpSendCustomEventToDebugger(writeParameterCommandPointer, Unsafe.SizeOf <WriteParameterCommand>()); // .. debugger magic ... the debuggerBuffer will be filled with parameter data TypesAndValues typesAndValues = new TypesAndValues(); uint trash; uint parameterCount; uint parameterValue; uint eeTypeCount; ulong eeType; uint offset = 0; NativeReader reader = new NativeReader(debuggerBufferRawPointer, parameterBufferSize); offset = reader.DecodeUnsigned(offset, out trash); // The VertexSequence always generate a length, I don't really need it. offset = reader.DecodeUnsigned(offset, out parameterCount); typesAndValues.parameterValues = new int[parameterCount]; for (int i = 0; i < parameterCount; i++) { offset = reader.DecodeUnsigned(offset, out parameterValue); typesAndValues.parameterValues[i] = (int)parameterValue; } offset = reader.DecodeUnsigned(offset, out eeTypeCount); for (int i = 0; i < eeTypeCount; i++) { // TODO: Stuff these eeType values into the external reference table offset = reader.DecodeUnsignedLong(offset, out eeType); } TypeSystemContext typeSystemContext = TypeSystemContextFactory.Create(); bool hasThis; TypeDesc[] parameters; bool[] parametersWithGenericDependentLayout; bool result = TypeLoaderEnvironment.Instance.GetCallingConverterDataFromMethodSignature_NativeLayout_Debugger(typeSystemContext, RuntimeSignature.CreateFromNativeLayoutSignatureForDebugger(offset), Instantiation.Empty, Instantiation.Empty, out hasThis, out parameters, out parametersWithGenericDependentLayout, reader); typesAndValues.types = new RuntimeTypeHandle[parameters.Length]; bool needToDynamicallyLoadTypes = false; for (int i = 0; i < typesAndValues.types.Length; i++) { if (!parameters[i].RetrieveRuntimeTypeHandleIfPossible()) { needToDynamicallyLoadTypes = true; break; } typesAndValues.types[i] = parameters[i].GetRuntimeTypeHandle(); } if (needToDynamicallyLoadTypes) { TypeLoaderEnvironment.Instance.RunUnderTypeLoaderLock(() => { typeSystemContext.FlushTypeBuilderStates(); GenericDictionaryCell[] cells = new GenericDictionaryCell[parameters.Length]; for (int i = 0; i < cells.Length; i++) { cells[i] = GenericDictionaryCell.CreateTypeHandleCell(parameters[i]); } IntPtr[] eetypePointers; TypeBuilder.ResolveMultipleCells(cells, out eetypePointers); for (int i = 0; i < parameters.Length; i++) { typesAndValues.types[i] = ((EEType *)eetypePointers[i])->ToRuntimeTypeHandle(); } }); } TypeSystemContextFactory.Recycle(typeSystemContext); LocalVariableType[] argumentTypes = new LocalVariableType[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { // TODO: What these false really means? Need to make sure our format contains those information argumentTypes[i] = new LocalVariableType(typesAndValues.types[i], false, false); } LocalVariableSet.SetupArbitraryLocalVariableSet <TypesAndValues>(HighLevelDebugFuncEvalHelperWithVariables, ref typesAndValues, argumentTypes); } }
public override GenericDictionaryCell GetDictionaryCell() { return(GenericDictionaryCell.CreateTypeHandleCell(Type)); }