Beispiel #1
0
        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();
            }
        }
Beispiel #2
0
        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();
            }
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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;
        }
Beispiel #5
0
        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();
            }
        }
Beispiel #6
0
        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() + ")");
            }
        }
Beispiel #7
0
        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();
            }
        }
Beispiel #8
0
        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();
            }
        }
Beispiel #9
0
        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();
            }
        }
Beispiel #10
0
 public MethodCodeNodeDebugView(MethodCodeNode node)
 {
     _node = node;
 }
Beispiel #11
0
        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();
            }
        }
Beispiel #12
0
        /// <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;
        }