public void CompileMethod(MethodCodeNode methodCodeNodeNeedingCode) { try { _methodCodeNode = methodCodeNodeNeedingCode; CORINFO_METHOD_INFO methodInfo; Get_CORINFO_METHOD_INFO(MethodBeingCompiled, out methodInfo); uint flags = (uint)( CorJitFlag.CORJIT_FLG_SKIP_VERIFICATION | CorJitFlag.CORJIT_FLG_READYTORUN | CorJitFlag.CORJIT_FLG_RELOC | CorJitFlag.CORJIT_FLG_DEBUG_INFO | CorJitFlag.CORJIT_FLG_PREJIT); if (!_compilation.Options.NoLineNumbers) { CompilerTypeSystemContext typeSystemContext = _compilation.TypeSystemContext; IEnumerable<ILSequencePoint> ilSequencePoints = typeSystemContext.GetSequencePointsForMethod(MethodBeingCompiled); if (ilSequencePoints != null) { Dictionary<int, SequencePoint> sequencePoints = new Dictionary<int, SequencePoint>(); foreach (var point in ilSequencePoints) { sequencePoints.Add(point.Offset, new SequencePoint() { Document = point.Document, LineNumber = point.LineNumber }); } _sequencePoints = sequencePoints; } } IntPtr exception; IntPtr nativeEntry; uint codeSize; JitWrapper(out exception, _jit, _comp, ref methodInfo, flags, out nativeEntry, out codeSize); if (exception != IntPtr.Zero) { char* szMessage = GetExceptionMessage(exception); string message = szMessage != null ? new string(szMessage) : "JIT Exception"; throw new Exception(message); } PublishCode(); } finally { CompileMethodCleanup(); } }
public void CompileMethod(MethodCodeNode methodCodeNodeNeedingCode) { try { _methodBeingCompiled = methodCodeNodeNeedingCode.Method; CORINFO_METHOD_INFO methodInfo; Get_CORINFO_METHOD_INFO(_methodBeingCompiled, out methodInfo); uint flags = (uint)( CorJitFlag.CORJIT_FLG_SKIP_VERIFICATION | CorJitFlag.CORJIT_FLG_READYTORUN | CorJitFlag.CORJIT_FLG_RELOC | CorJitFlag.CORJIT_FLG_DEBUG_INFO | CorJitFlag.CORJIT_FLG_PREJIT); if (!_compilation.Options.NoLineNumbers) { CompilerTypeSystemContext typeSystemContext = _compilation.TypeSystemContext; IEnumerable<ILSequencePoint> ilSequencePoints = typeSystemContext.GetSequencePointsForMethod(_methodBeingCompiled); if (ilSequencePoints != null) { Dictionary<int, SequencePoint> sequencePoints = new Dictionary<int, SequencePoint>(); foreach (var point in ilSequencePoints) { sequencePoints.Add(point.Offset, new SequencePoint() { Document = point.Document, LineNumber = point.LineNumber }); } _sequencePoints = sequencePoints; } } IntPtr nativeEntry; uint codeSize; _compile(_jit, _comp, ref methodInfo, flags, out nativeEntry, out codeSize); PublishCode(methodCodeNodeNeedingCode); } finally { FlushPins(); } }
private void PublishCode(MethodCodeNode methodCodeNodeNeedingCode) { var relocs = _relocs.ToArray(); Array.Sort(relocs, (x, y) => (x.Offset - y.Offset)); var objectData = new ObjectNode.ObjectData(_code, relocs, _compilation.NodeFactory.Target.MinimumFunctionAlignment, new ISymbolNode[] { methodCodeNodeNeedingCode }); methodCodeNodeNeedingCode.SetCode(objectData); methodCodeNodeNeedingCode.InitializeFrameInfos(_frameInfos); methodCodeNodeNeedingCode.InitializeDebugLocInfos(_debugLocInfos); }
private void CompileMethodCleanup() { foreach (var pin in _pins) pin.Value.Free(); _pins.Clear(); if (_nativeExceptions != null) { foreach (IntPtr ex in _nativeExceptions) FreeException(ex); _nativeExceptions = null; } _methodCodeNode = null; _code = null; _coldCode = null; _roData = null; _roDataBlob = null; _relocs = new ArrayBuilder<Relocation>(); _numFrameInfos = 0; _usedFrameInfos = 0; _frameInfos = null; _ehClauses = null; _sequencePoints = null; _debugLocInfos = null; _debugVarInfos = null; _lastException = null; }
private CORINFO_MODULE_STRUCT_* _methodScope; // Needed to resolve CORINFO_EH_CLAUSE tokens public void CompileMethod(MethodCodeNode methodCodeNodeNeedingCode, MethodIL methodIL = null) { try { _methodCodeNode = methodCodeNodeNeedingCode; CORINFO_METHOD_INFO methodInfo; methodIL = Get_CORINFO_METHOD_INFO(MethodBeingCompiled, methodIL, out methodInfo); // This is e.g. an "extern" method in C# without a DllImport or InternalCall. if (methodIL == null) { throw new TypeSystemException.InvalidProgramException(ExceptionStringID.InvalidProgramSpecific, MethodBeingCompiled); } _methodScope = methodInfo.scope; try { MethodDebugInformation debugInfo = _compilation.GetDebugInfo(methodIL); if (!_compilation.Options.NoLineNumbers) { IEnumerable<ILSequencePoint> ilSequencePoints = debugInfo.GetSequencePoints(); if (ilSequencePoints != null) { SetSequencePoints(ilSequencePoints); } } IEnumerable<ILLocalVariable> localVariables = debugInfo.GetLocalVariables(); if (localVariables != null) { SetLocalVariables(localVariables); } IEnumerable<string> parameters = debugInfo.GetParameterNames(); if (parameters != null) { SetParameterNames(parameters); } } catch (Exception e) { // Debug info not successfully loaded. _compilation.Log.WriteLine(e.Message + " (" + methodCodeNodeNeedingCode.ToString() + ")"); } CorInfoImpl _this = this; IntPtr exception; IntPtr nativeEntry; uint codeSize; var result = JitCompileMethod(out exception, _jit, (IntPtr)Unsafe.AsPointer(ref _this), _unmanagedCallbacks, ref methodInfo, (uint)CorJitFlag.CORJIT_FLG_CALL_GETJITFLAGS, out nativeEntry, out codeSize); if (exception != IntPtr.Zero) { if (_lastException != null) { // If we captured a managed exception, rethrow that. // TODO: might not actually be the real reason. It could be e.g. a JIT failure/bad IL that followed // an inlining attempt with a type system problem in it... throw _lastException; } // This is a failure we don't know much about. char* szMessage = GetExceptionMessage(exception); string message = szMessage != null ? new string(szMessage) : "JIT Exception"; throw new Exception(message); } if (result == CorJitResult.CORJIT_BADCODE) { throw new TypeSystemException.InvalidProgramException(ExceptionStringID.InvalidProgramSpecific, MethodBeingCompiled); } if (result != CorJitResult.CORJIT_OK) { throw new Exception("JIT Failed"); } PublishCode(); } finally { CompileMethodCleanup(); } }
private void SetDebugInformation(MethodCodeNode methodCodeNodeNeedingCode, MethodIL methodIL) { try { MethodDebugInformation debugInfo = _compilation.GetDebugInfo(methodIL); // TODO: NoLineNumbers //if (!_compilation.Options.NoLineNumbers) { IEnumerable<ILSequencePoint> ilSequencePoints = debugInfo.GetSequencePoints(); if (ilSequencePoints != null) { SetSequencePoints(ilSequencePoints); } } IEnumerable<ILLocalVariable> localVariables = debugInfo.GetLocalVariables(); if (localVariables != null) { SetLocalVariables(localVariables); } IEnumerable<string> parameters = debugInfo.GetParameterNames(); if (parameters != null) { SetParameterNames(parameters); } ArrayBuilder<uint> variableToTypeIndex = new ArrayBuilder<uint>(); var signature = MethodBeingCompiled.Signature; if (!signature.IsStatic) { TypeDesc type = MethodBeingCompiled.OwningType; variableToTypeIndex.Add(GetVariableTypeIndex(type)); } for (int i = 0; i < signature.Length; ++i) { TypeDesc type = signature[i]; variableToTypeIndex.Add(GetVariableTypeIndex(type)); } var locals = methodIL.GetLocals(); for (int i = 0; i < locals.Length; ++i) { TypeDesc type = locals[i].Type; variableToTypeIndex.Add(GetVariableTypeIndex(type)); } _variableToTypeIndex = variableToTypeIndex.ToArray(); } catch (Exception e) { // Debug info not successfully loaded. Log.WriteLine(e.Message + " (" + methodCodeNodeNeedingCode.ToString() + ")"); } }
private bool _isFallbackBodyCompilation; // True if we're compiling a fallback method body after compiling the real body failed public void CompileMethod(MethodCodeNode methodCodeNodeNeedingCode, MethodIL methodIL = null) { try { _methodCodeNode = methodCodeNodeNeedingCode; _isFallbackBodyCompilation = methodIL != null; CORINFO_METHOD_INFO methodInfo; methodIL = Get_CORINFO_METHOD_INFO(MethodBeingCompiled, methodIL, out methodInfo); // This is e.g. an "extern" method in C# without a DllImport or InternalCall. if (methodIL == null) { throw new TypeSystemException.InvalidProgramException(ExceptionStringID.InvalidProgramSpecific, MethodBeingCompiled); } _methodScope = methodInfo.scope; SetDebugInformation(methodCodeNodeNeedingCode, methodIL); CorInfoImpl _this = this; IntPtr exception; IntPtr nativeEntry; uint codeSize; var result = JitCompileMethod(out exception, _jit, (IntPtr)Unsafe.AsPointer(ref _this), _unmanagedCallbacks, ref methodInfo, (uint)CorJitFlag.CORJIT_FLAG_CALL_GETJITFLAGS, out nativeEntry, out codeSize); if (exception != IntPtr.Zero) { if (_lastException != null) { // If we captured a managed exception, rethrow that. // TODO: might not actually be the real reason. It could be e.g. a JIT failure/bad IL that followed // an inlining attempt with a type system problem in it... _lastException.Throw(); } // This is a failure we don't know much about. char* szMessage = GetExceptionMessage(exception); string message = szMessage != null ? new string(szMessage) : "JIT Exception"; throw new Exception(message); } if (result == CorJitResult.CORJIT_BADCODE) { throw new TypeSystemException.InvalidProgramException(ExceptionStringID.InvalidProgramSpecific, MethodBeingCompiled); } if (result != CorJitResult.CORJIT_OK) { throw new Exception("JIT Failed"); } PublishCode(); } finally { CompileMethodCleanup(); } }
private CORINFO_MODULE_STRUCT_* _methodScope; // Needed to resolve CORINFO_EH_CLAUSE tokens public void CompileMethod(MethodCodeNode methodCodeNodeNeedingCode) { try { _methodCodeNode = methodCodeNodeNeedingCode; CORINFO_METHOD_INFO methodInfo; Get_CORINFO_METHOD_INFO(MethodBeingCompiled, out methodInfo); _methodScope = methodInfo.scope; try { CompilerTypeSystemContext typeSystemContext = _compilation.TypeSystemContext; if (!_compilation.Options.NoLineNumbers) { IEnumerable<ILSequencePoint> ilSequencePoints = typeSystemContext.GetSequencePointsForMethod(MethodBeingCompiled); if (ilSequencePoints != null) { SetSequencePoints(ilSequencePoints); } } IEnumerable<ILLocalVariable> localVariables = typeSystemContext.GetLocalVariableNamesForMethod(MethodBeingCompiled); if (localVariables != null) { SetLocalVariables(localVariables); } IEnumerable<string> parameters = typeSystemContext.GetParameterNamesForMethod(MethodBeingCompiled); if (parameters != null) { SetParameterNames(parameters); } } catch (Exception e) { // Debug info not successfully loaded. _compilation.Log.WriteLine(e.Message + " (" + methodCodeNodeNeedingCode.GetName() + ")"); } IntPtr exception; IntPtr nativeEntry; uint codeSize; JitWrapper(out exception, _jit, _comp, ref methodInfo, (uint)CorJitFlag.CORJIT_FLG_CALL_GETJITFLAGS, out nativeEntry, out codeSize); if (exception != IntPtr.Zero) { char* szMessage = GetExceptionMessage(exception); string message = szMessage != null ? new string(szMessage) : "JIT Exception"; throw new Exception(message); } PublishCode(); } finally { CompileMethodCleanup(); } }
private CORINFO_MODULE_STRUCT_* _methodScope; // Needed to resolve CORINFO_EH_CLAUSE tokens public void CompileMethod(MethodCodeNode methodCodeNodeNeedingCode) { try { _methodCodeNode = methodCodeNodeNeedingCode; CORINFO_METHOD_INFO methodInfo; MethodIL methodIL = Get_CORINFO_METHOD_INFO(MethodBeingCompiled, out methodInfo); _methodScope = methodInfo.scope; try { CompilerTypeSystemContext typeSystemContext = _compilation.TypeSystemContext; MethodDebugInformation debugInfo = _compilation.GetDebugInfo(methodIL); if (!_compilation.Options.NoLineNumbers) { IEnumerable<ILSequencePoint> ilSequencePoints = debugInfo.GetSequencePoints(); if (ilSequencePoints != null) { SetSequencePoints(ilSequencePoints); } } IEnumerable<ILLocalVariable> localVariables = debugInfo.GetLocalVariables(); if (localVariables != null) { SetLocalVariables(localVariables); } IEnumerable<string> parameters = debugInfo.GetParameterNames(); if (parameters != null) { SetParameterNames(parameters); } } catch (Exception e) { // Debug info not successfully loaded. _compilation.Log.WriteLine(e.Message + " (" + methodCodeNodeNeedingCode.GetName() + ")"); } CorInfoImpl _this = this; IntPtr exception; IntPtr nativeEntry; uint codeSize; var result = JitCompileMethod(out exception, _jit, (IntPtr)Unsafe.AsPointer(ref _this), _unmanagedCallbacks, ref methodInfo, (uint)CorJitFlag.CORJIT_FLG_CALL_GETJITFLAGS, out nativeEntry, out codeSize); if (exception != IntPtr.Zero) { char* szMessage = GetExceptionMessage(exception); string message = szMessage != null ? new string(szMessage) : "JIT Exception"; throw new Exception(message); } if (result != CorJitResult.CORJIT_OK) { throw new Exception("JIT Failed"); } PublishCode(); } finally { CompileMethodCleanup(); } }
public MethodCodeNodeDebugView(MethodCodeNode node) { _node = node; }
public void CompileMethod(MethodCodeNode methodCodeNodeNeedingCode) { try { _methodCodeNode = methodCodeNodeNeedingCode; CORINFO_METHOD_INFO methodInfo; Get_CORINFO_METHOD_INFO(MethodBeingCompiled, out methodInfo); uint flags = (uint)( CorJitFlag.CORJIT_FLG_SKIP_VERIFICATION | CorJitFlag.CORJIT_FLG_READYTORUN | CorJitFlag.CORJIT_FLG_RELOC | CorJitFlag.CORJIT_FLG_DEBUG_INFO | CorJitFlag.CORJIT_FLG_PREJIT); if (_compilation.Options.TargetOS != TargetOS.Windows) { flags |= (uint) CorJitFlag.CORJIT_FLG_CFI_UNWIND; } try { CompilerTypeSystemContext typeSystemContext = _compilation.TypeSystemContext; if (!_compilation.Options.NoLineNumbers) { IEnumerable<ILSequencePoint> ilSequencePoints = typeSystemContext.GetSequencePointsForMethod(MethodBeingCompiled); if (ilSequencePoints != null) { SetSequencePoints(ilSequencePoints); } } IEnumerable<ILLocalVariable> localVariables = typeSystemContext.GetLocalVariableNamesForMethod(MethodBeingCompiled); if (localVariables != null) { SetLocalVariables(localVariables); } IEnumerable<string> parameters = typeSystemContext.GetParameterNamesForMethod(MethodBeingCompiled); if (parameters != null) { SetParameterNames(parameters); } } catch (Exception e) { // Debug info not successfully loaded. _compilation.Log.WriteLine(e.Message + " (" + methodCodeNodeNeedingCode.GetName() + ")"); } IntPtr exception; IntPtr nativeEntry; uint codeSize; JitWrapper(out exception, _jit, _comp, ref methodInfo, flags, out nativeEntry, out codeSize); if (exception != IntPtr.Zero) { char* szMessage = GetExceptionMessage(exception); string message = szMessage != null ? new string(szMessage) : "JIT Exception"; throw new Exception(message); } PublishCode(); } finally { CompileMethodCleanup(); } }
/// <summary> /// Compiles the provided method code node while swapping it's body with a throwing stub. /// </summary> private bool TryCompileWithThrowingBody(MethodCodeNode methodNode, TypeSystemException exception) { MethodDesc helper; Type exceptionType = exception.GetType(); if (exceptionType == typeof(TypeSystemException.TypeLoadException)) { helper = _typeSystemContext.GetHelperEntryPoint("ThrowHelpers", "ThrowTypeLoadException"); } else if (exceptionType == typeof(TypeSystemException.MissingFieldException)) { helper = _typeSystemContext.GetHelperEntryPoint("ThrowHelpers", "ThrowMissingFieldException"); } else if (exceptionType == typeof(TypeSystemException.MissingMethodException)) { helper = _typeSystemContext.GetHelperEntryPoint("ThrowHelpers", "ThrowMissingMethodException"); } else if (exceptionType == typeof(TypeSystemException.FileNotFoundException)) { helper = _typeSystemContext.GetHelperEntryPoint("ThrowHelpers", "ThrowFileNotFoundException"); } else if (exceptionType == typeof(TypeSystemException.InvalidProgramException)) { helper = _typeSystemContext.GetHelperEntryPoint("ThrowHelpers", "ThrowInvalidProgramException"); } else { return false; } Debug.Assert(helper.Signature.Length == exception.Arguments.Count + 1); var emitter = new Internal.IL.Stubs.ILEmitter(); var codeStream = emitter.NewCodeStream(); var infinityLabel = emitter.NewCodeLabel(); codeStream.EmitLabel(infinityLabel); codeStream.EmitLdc((int)exception.StringID); foreach (var arg in exception.Arguments) { codeStream.Emit(ILOpcode.ldstr, emitter.NewToken(arg)); } codeStream.Emit(ILOpcode.call, emitter.NewToken(helper)); // The call will never return, but we still need to emit something. Emit a jump so that // we don't have to bother balancing the stack if the method returns something. codeStream.Emit(ILOpcode.br, infinityLabel); _corInfo.CompileMethod(methodNode, emitter.Link(methodNode.Method)); return true; }