<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr">Hi All,<div><br></div><div>A preliminary version of removable code support has been posted for review in <a href="https://reviews.llvm.org/D79312">https://reviews.llvm.org/D79312</a>. This patch removes all uses of VModuleKeys (except for Legacy layers) and takes a whole-JITDylib-at-a-time approach to removal. Removing whole JITDylibs requires more work from clients (compared to per-module removal): Modules to be removed must be placed into throw-away JITDylibs and re-exports used to make symbol definitions visible at the intended locations. On the other hand restricting removal to whole JITDylibs can help to avoid subtle dependence bugs: existing object formats and linker rules are already designed to make independently loading and unloading libraries relatively safe, whereas there is no precedent for unloading individual modules from within a library at runtime.</div><div><br></div><div>As an example of how unloading individual modules can lead to subtle dependence bugs consider the following REPL for a simple language (Kaleidoscope from <a href="https://llvm.org/docs/tutorial/">https://llvm.org/docs/tutorial/</a>). In this example the REPL values will all be of floating point type, functions will be compiled lazily, and anonymous expressions will be removed immediately after running them. Under these assumptions, how does the REPL respond to the following input?</div><div><br></div><div><font face="monospace">repl> def foo(x) x * 2.0;</font></div><div><font face="monospace">repl> foo(2.0) + 1.0;</font></div><div><font face="monospace">// output #1 here</font></div><div><font face="monospace">// anonymous expression #1 removed here</font></div><div><font face="monospace">repl> foo(3.0);<br></font></div><div><font face="monospace">// output #2 here</font></div><div><font face="monospace">// anonymous expression #2 removed here</font></div><div><br></div><div>We expect the result to be:</div><div><br></div><div><font face="monospace">output #1: 5.0<br></font></div><div><font face="monospace">output #2: 6.0</font></div><div><br></div><div>And on Linux and Darwin it will be. On Windows however, the output is likely* to be:</div><div><font face="monospace"><br></font></div><div><font face="monospace">output #1: 5.0</font></div><div><font face="monospace">output #2: segfault</font></div><div><br></div><div>(*The exact output will depend on the target options used).</div><div><br></div><div>The problem is that when compiling to COFF (the Windows relocatable object file format) floating point constants may be stored in named COMDAT entries (See e.g. <a href="https://llvm.org/PR40074">https://llvm.org/PR40074</a>). Only one copy of a constant value is emitted, and other modules will be linked to refer to that copy. In our example, because of lazy compilation, the first copy of the constant 2.0 that the JIT linker will encounter is the one used in anonymous expression #1. The body of foo will link against this copy and  be left with a dangling reference when anonymous expression #1 is deleted. Attempting to re-run the foo function in anonymous expression #2 will then crash.</div><div><br></div><div>The COFF format and linker rules already ensure that dynamic libraries each get their own copies of their floating point constants, so by following the existing rules and only allowing per-JITDylib removal this case becomes safe.</div><div><br></div><div>There's plenty more to talk about here, but it's getting late so I'll leave it here for tonight. Questions and comments on this approach and the initial patch are very welcome, especially from people who have use-cases for removing code. Barring any major objections I'm hoping that we can have this feature in-tree in the next week or so.</div><div><br></div><div>-- Lang.</div><div><br></div><div><br></div></div></div></div></div></div>