|
1 | | -.NET Framework 4.6 - Testing RyuJIT |
2 | | -=================================== |
| 1 | +.NET Framework 4.6 - Troubleshooing RyuJIT |
| 2 | +========================================== |
3 | 3 |
|
4 | | -The [.NET Framework 4.6](http://blogs.msdn.com/b/dotnet/archive/2015/07/20/announcing-net-framework-4-6.aspx#net-framework-46) includes new Just-In-Time (JIT) compiler for 64-bit processes, called RyuJIT. It is enabled by default. |
| 4 | +The [.NET Framework 4.6](http://blogs.msdn.com/b/dotnet/archive/2015/07/20/announcing-net-framework-4-6.aspx#net-framework-46) includes a new Just-In-Time (JIT) compiler for 64-bit processes, called RyuJIT. It is enabled by default. Note that the 32-bit JIT in .NET Framework 4.6 is not significantly changed from previous releases. This document does not describe troubleshooting problems with the 32-bit JIT. |
5 | 5 |
|
6 | | -This document provides instructions to disable RyuJIT or one of its optimizations, in order to test your program without it running. This is useful if you experience unexpected product behavior and want to determine if RyuJIT is the cause of that behavioral change. |
| 6 | +This document provides instructions to disable RyuJIT or one of its optimizations. This is useful if you experience unexpected product behavior after installing .NET Framework 4.6 and want to determine if RyuJIT is the cause of that behavioral change. |
7 | 7 |
|
8 | | -Disable RyuJIT |
9 | | -============== |
| 8 | +If you find a problem that appears to be a bug with the .NET JIT compiler, we want to know about it! Please report the bug here: https://connect.microsoft.com/VisualStudio. |
10 | 9 |
|
11 | | -**Important** Follow the steps in this section carefully. Serious problems might |
| 10 | +**Important** Follow the steps in this document carefully. Serious problems might |
12 | 11 | occur if you modify the registry incorrectly. Before you modify it, |
13 | 12 | [back up the registry](http://support.microsoft.com/kb/322756) for restoration |
14 | 13 | in case problems occur. |
15 | 14 |
|
16 | | -**Note** For all these methods, all dynamic compilation is performed by the older |
17 | | -JIT64 JIT. Also, all NGEN compilation continues to use the new JIT, and all |
18 | | -existing NGEN images that have been compiled by the new JIT continue to be used. |
19 | | - |
20 | | -* **Method 1**. Set the following environment variable: |
21 | | - |
22 | | - COMPLUS_useLegacyJit=1 |
23 | | - |
24 | | -* **Method 2**. In the registry, create either of the following subkeys: |
25 | | - |
26 | | - HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework |
27 | | - HKEY_CURRENT_USER\SOFTWARE\Microsoft\.NETFramework |
| 15 | +**Note** The registry methods below use either `HKEY_LOCAL_MACHINE` or `HKEY_CURRENT_USER`. Using `HKEY_LOCAL_MACHINE` makes the setting applicable to the entire machine and all users. Using `HKEY_CURRENT_USER` makes the setting applicable to just the current user. If using the registry methods, the latter is generally preferable. |
28 | 16 |
|
29 | | - Then, specify the following: |
| 17 | +Disable RyuJIT |
| 18 | +============== |
30 | 19 |
|
31 | | - Key name: useLegacyJit |
32 | | - Type: REG_WORD |
33 | | - Value: 1 |
| 20 | +**Note** For all these methods, all dynamic compilation is performed by the older |
| 21 | +"legacy" JIT (sometimes known as JIT64). All NGEN compilation continues to use the new JIT, and all |
| 22 | +existing NGEN images that have been compiled by the new JIT continue to be used. |
34 | 23 |
|
35 | | -* **Method 3**. Add the following text to the `<app>.exe.config file`. Create |
| 24 | +* **Method 1: per-application config file**. Add the following text to the `<app>.exe.config` file. Create |
36 | 25 | the indicated sections if they do not already exist. |
37 | 26 |
|
38 | 27 | **Note** In this file name, `<app>` represents the actual name of the |
39 | | - application. |
| 28 | + application. So, for example, for `MyApp.exe`, you will have `MyApp.exe.config`. |
40 | 29 |
|
41 | 30 | <configuration> |
42 | 31 | <runtime> |
43 | 32 | <useLegacyJit enabled="1"> |
44 | 33 | </runtime> |
45 | 34 | </configuration> |
46 | 35 |
|
47 | | -Disable loading NGEN Images |
48 | | -=========================== |
49 | | - |
50 | | -If you encounter a bug when you use the new JIT, and if the bug manifests itself |
51 | | -as an NGEN image, use any of the following methods to force certain named |
52 | | -assemblies to be recompiled by the JIT and not use the existing native images: |
| 36 | + Note that Method 1 does not apply to ASP.NET websites; you cannot use this method in web.config files. |
| 37 | + |
| 38 | + This method is preferable as it is scoped to just one application. |
53 | 39 |
|
54 | | -* **Method 1**. Set the following environment variable: |
| 40 | +* **Method 2: environment variable**. Set the following environment variable: |
55 | 41 |
|
56 | | - COMPLUS_DisableNativeImageLoadList=assembly_one;assembly_two;assembly_three |
| 42 | + COMPLUS_useLegacyJit=1 |
57 | 43 |
|
58 | | -* **Method 2**. In the registry, create either of the following subkeys: |
| 44 | + This method affects any environment that inherits this environment variable. This might be just a single |
| 45 | + console session, or it might affect the entire machine, if you set the environment variable globally. |
| 46 | + |
| 47 | +* **Method 3: registry**. Using Registry Editor (regedit.exe), find either of the following subkeys: |
59 | 48 |
|
60 | 49 | HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework |
61 | 50 | HKEY_CURRENT_USER\SOFTWARE\Microsoft\.NETFramework |
62 | 51 |
|
63 | | - Then, specify the following: |
| 52 | + Then, add the following: |
64 | 53 |
|
65 | | - Key name: DisableNativeImageLoadList |
66 | | - Type: REG_SZ |
67 | | - Value: assembly_one;assembly_two;assembly_three |
| 54 | + Value name: useLegacyJit |
| 55 | + Type: DWORD (32-bit) Value (also called REG_WORD) |
| 56 | + Value: 1 |
68 | 57 |
|
69 | | - **Note** This is a semicolon-delimited or space-delimited list of simple |
70 | | - assembly names (no public key token, no architecture, and so on). This list |
71 | | - does not contain the `.dll` file name extension. In the examples in this |
72 | | - method and the next method, `assembly_one` is the simple name for an assembly |
73 | | - that is named `assembly_one.dll`. |
| 58 | +Disable loading NGEN Images |
| 59 | +=========================== |
74 | 60 |
|
75 | | -* **Method 3**. Add the following text to the `<app>.exe.config` file. Create |
| 61 | +If you encounter a bug when you use the new JIT, and if the bug manifests itself |
| 62 | +in an NGEN image, use any of the following methods to force certain named |
| 63 | +assemblies to be recompiled by the JIT and not use the existing native images. You |
| 64 | +will generally pair one of these methods with the same numbered method above to get an NGEN image |
| 65 | +to fall back to JIT compilation, and, in addition, do that JIT compilation with the legacy |
| 66 | +JIT. |
| 67 | + |
| 68 | +In the examples below, we wish to prevent using the NGEN images of three assemblies, named |
| 69 | +`assembly_one.dll`, `assembly_two.dll`, and `assembly_three.dll`. We specify the assemblies |
| 70 | +using simple assembly names (no public key token, no architecture, and so on). The assembly names |
| 71 | +are specified without using the `.dll` file name extension. |
| 72 | + |
| 73 | +* **Method 1: : per-application config file**. Add the following text to the `<app>.exe.config` file. Create |
76 | 74 | the indicated sections if they do not already exist. |
77 | 75 |
|
78 | | - **Note** In this file name, `<app>` represents the actual name of the |
79 | | - application. |
| 76 | + **Note** In this file name, `<app>` represents the actual name of the application. |
80 | 77 |
|
81 | 78 | <configuration> |
82 | 79 | <runtime> |
83 | | - <disableNativeImageLoad> |
84 | | - <assemblyIdentity name="assembly_one" /> |
85 | | - <assemblyIdentity name="assembly_two" /> |
86 | | - </disableNativeImageLoad> |
| 80 | + <disableNativeImageLoad> |
| 81 | + <assemblyIdentity name="assembly_one" /> |
| 82 | + <assemblyIdentity name="assembly_two" /> |
| 83 | + <assemblyIdentity name="assembly_three" /> |
| 84 | + </disableNativeImageLoad> |
87 | 85 | </runtime> |
88 | 86 | </configuration> |
89 | 87 |
|
| 88 | +* **Method 2: environment variable**. Set the following environment variable: |
| 89 | + |
| 90 | + COMPLUS_DisableNativeImageLoadList=assembly_one;assembly_two;assembly_three |
| 91 | + |
| 92 | + **Note** This is a semicolon-delimited list of simple assembly names. |
| 93 | + |
| 94 | +* **Method 3: registry**. Using Registry Editor (regedit.exe), find either of the following subkeys: |
| 95 | + |
| 96 | + HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework |
| 97 | + HKEY_CURRENT_USER\SOFTWARE\Microsoft\.NETFramework |
| 98 | + |
| 99 | + Then, add the following value: |
| 100 | + |
| 101 | + Value name: DisableNativeImageLoadList |
| 102 | + Type: String Value (also known as REG_SZ) |
| 103 | + Value: assembly_one;assembly_two;assembly_three |
| 104 | + |
| 105 | + **Note** This is a semicolon-delimited list of simple assembly names. |
| 106 | + |
90 | 107 | Disable Tail Call Optimization |
91 | 108 | ============================== |
92 | 109 |
|
93 | 110 | You can disable tail call optimization in RyuJIT with the following instructions. |
94 | 111 |
|
95 | | -* In the registry, create either of the following subkeys: |
| 112 | +* Using Registry Editor (regedit.exe), find either of the following subkeys: |
96 | 113 |
|
97 | 114 | HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework |
98 | 115 | HKEY_CURRENT_USER\SOFTWARE\Microsoft\.NETFramework |
99 | 116 |
|
100 | | - Then, specify the following: |
| 117 | + Then, add the following value: |
| 118 | + |
| 119 | + Value name: TailCallOpt |
| 120 | + Type: String Value (also known as REG_SZ) |
| 121 | + Value: "0" (Double quotes are not required while entering the string value in Registry Editor) |
| 122 | + |
| 123 | +Disabling optimization of a function |
| 124 | +==================================== |
| 125 | + |
| 126 | +You can selectively disable JIT optimization of a particular function by annotating that function with `MethodImplOptions.NoOptimization`. For example, in C#: |
| 127 | + |
| 128 | + using System.Runtime.CompilerServices; |
| 129 | + ... |
| 130 | + [MethodImplAttribute(MethodImplOptions.NoOptimization)] |
| 131 | + static int add(int a, int b) |
| 132 | + { |
| 133 | + return a + b; |
| 134 | + } |
| 135 | + |
| 136 | +In this case, the annotated `add` function will not be optimized. You can see more detail about `MethodImplAttribute` |
| 137 | +[here](https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.methodimplattribute(v=vs.110).aspx). |
| 138 | + |
| 139 | +Note that this method applies to all .NET JIT compilers. |
| 140 | + |
| 141 | +Additional Notes |
| 142 | +================ |
| 143 | + |
| 144 | +If you are examining the registry, you might find the following registry value: |
| 145 | + |
| 146 | + HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\UseRyuJIT |
101 | 147 |
|
102 | | - Key name: TailCallOpt |
103 | | - Type: REG_SZ |
104 | | - Value: "0" (Double quotes are not required while entering in Registry editor) |
| 148 | +We urge you not to change this value. Instead, use the RyuJIT fallback mechanisms detailed above in this document. |
0 commit comments