-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement custom memory manager for LLVM #16777
Conversation
|
at present, this has been blocked on the need to write our own custom memory manager (specifically, one that supports the small memory model required by ntdll on win64 for all dynamic libraries), and then patch the LLVM runtime relocation code to add support for the ADDR32NB relocation type. |
What's the requirement? All sections to be smaller and within 4G to each other? The current custom memory manager doesn't do that yet but it's not that hard to add (especially if we can use the reserve function). |
yes, and consecutively allocated (images must be non-overlapping and can't be interleaved) |
Doesn't this require the current allocation scheme? The page' where we have allocations in basically can't be reused anymore. (edit: or no W^X) |
Or maybe we can waste virtual memory but not physical memory? |
I'm not sure. It appears that the actual requirements are undocumented and considered to be an implementation detail. We may be able to get away with some lying, since we are JIT and not statically linked. But unfortunately, there's no way to verify the source code of ntdll to learn it's expectations. |
Why would there be an expectation that the sections are non-interleaved? |
Actually, maybe only dbghelp cares (https://msdn.microsoft.com/en-us/library/windows/desktop/ms681353(v=vs.85).aspx), so perhaps it would only cause problems for WinDbg, but not ntdll. |
b9a83ae
to
c63e4ae
Compare
7159938
to
e855467
Compare
@@ -129,8 +131,17 @@ static void addOptimizationPasses(T *PM) | |||
//PM->add(createCFGSimplificationPass()); // Merge & remove BBs | |||
} | |||
|
|||
#ifdef USE_MCJIT | |||
RTDyldMemoryManager* createRTDyldMemoryManager(void); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this to codegen_internal.h as well.
73dbc4f
to
07ea952
Compare
I think I addressed all the comments apart from the one about cache flushing. I was hoping that |
07ea952
to
6d79549
Compare
Use various ways to reuse the page that has the page protection set in order to avoid wasting a page of memory for each JIT event. Fixes #14626
6d79549
to
8533a1c
Compare
@yuyichao I think this should be merged. Will you do the honor? |
Sure, I was just waiting for one of you to merge it ;-p |
This may be triggering a compiler bug in gcc 4.8, complaining that the copy constructor of Block was deleted (even though the use in question should have been a move constructor). We may have to comment out that deletion for the GCC 4.8 series. |
Where does it need a copy constructor for |
See buildbot log if it's more useful - https://build.julialang.org/builders/build_ubuntu14.04-x64/builds/940/steps/shell_1/logs/stdio |
|
That one is supposed to use a placement new with the default constructor... I guess the LLVM 3.7 |
What default constructor would it be using? How would it get the Block into its storage without using the move constructor? |
|
So you were relying on that particular function not being instantiated because you're not using it? |
And I want to make sure I don't copy/move it accidentally since it can cause memory leak or memory free'd at the wrong time. |
Make the move constructor |
Actually moving construct is always fine, moving assignment is not and is deleted. I've updated #16950 to implement the moving constructor properly. |
|
||
static int init_self_mem() | ||
{ | ||
int fd = open("/proc/self/mem", O_RDWR | O_SYNC | O_CLOEXEC); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to check before using O_CLOEXEC
https://build.julialang.org/builders/package_tarball64/builds/475/steps/make%20binary-dist/logs/stdio
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That kernel is actually too old for this method to work although I guess we should still compile this method for this to be included in the generic binary.... Should be fixed in 3f4e1e7
BTW, the memory savings from this is absolutely great. Awesome work @yuyichao ! |
Use various ways to reuse the page that has the page protection set in order to avoid wasting a page of memory for each JIT event.
Fixes #14626
Tested on Linux with LLVM 3.7.1 and 3.8 with OrcJIT.
This reduces the memory used in the subarray test by
~100MB
(There are around25k
JIT events each page protects at least one page of memory even though the total allocation is only around10-20MB
.)Should in principle work on OSX, using the
mkstemp
tmpfile
fallback code path.Does not work on windows yet due to how we handle windows unwinding (we patch the code section after the code is generated, causing a segfault since the load address is never writable). It might be enough to modify those code to write to local address instead of load address. @Keno also mentioned some way to fix this properly. (This is what the request for help is mainly for....)Fixed