RFR: 8234930: Use MAP_JIT when allocating pages for code cache on macOS
Anton Kozlov
akozlov at openjdk.java.net
Mon Sep 28 20:21:24 UTC 2020
On Mon, 28 Sep 2020 11:51:24 GMT, Anton Kozlov <akozlov at openjdk.org> wrote:
>> @tstuefe My patch to remove MAP_FIXED from the memory reservation path should make it possible to revert all the
>> os::reserve_memory changes in this patch.
>
> Interesting, thanks! I haven't evaluated the interface, just because it seemed to be out of scope for the task. I'll
> take a look and update the patch.
Hi,
> Can we on MacOS not use mmap at os::commit_memory, like we do on other platforms? In os::commit_memory, the exec
> parameter exists but on MacOS it is ignored.
Unfortunately, no. It's commit_memory uses MAP_FIXED that is incompatible with MAP_JIT. So it is impossible to commit
executable mapping, as commit is always MAP_FIXED. This change proposes a kind of 2-step mapping: MAP_JIT in reserve
and mprotect-without-mmap in commit.
> We now have to specify "exec" as parameter to os::reverve_memory(). This is another new restriction - before, I could
> theoretically reserve one mapping and commit various parts of it with and without exec flag. With this change, the
> whole mapping has to be either exec or !exec.
I think this is a major point in how the interface can be perceived. I assumed reserve to be semantically equivalent to
mmap. And commit/uncommit only to control how much memory is actually allocated in the mmaping. E.g. commit could only
follow reserve and commit could only refer to a (part of) memory reserved. So it would be natural for reserve to
dictate exec or !exec mode for commit in its memory region.
Do you think it will be a bad thing? I.e. to allow exec commit only in exec reserved mapping? Apparently, there was no
demand to do the opposite before. For that, it is still possible to reserve another !exec mapping beside.
> Why does os::uncommit_memory() now require "exec" as parameter? I know why you do it, but semantically it has no
> meaning. I should be able to uncommit memory without knowing the exact flags the mapping had been established with. So
> now the user has to carry this information and provide it back to the API when uncommitting? Right now probably all
> uncommits happen in areas where the exec information is implicit by its usage, but who says this is always the case?
I would propose for reserve, commit, uncommit to take a uniform set of parameters to model an object of a (missing)
"mapping" class, which would contain a meta-information about e.g. permissions. Now the meta-information is available
in the context, as you correctly have noted, so we don't really need to introduce the real object and class.
It is hard for me to imagine a case for "uncommit region regardless exec/!exec permission" that would really justify
the need for such uncommit request.
So I would propose to consider executable and nonexecutable mappings rather different, as 1) it is required by some
platforms like macOS, and 2) it is supported by the fact that now we know the exec/!exec type of a mapping when we work
with it (e.g. heap vs codecache). To continue the trend of the cleanup and to highlight the difference, it is possible
to create specialized code_reserve/commit/uncommit that will be implemented with usual reserve/... on all platforms
except macOS, and latter to use MAP_JIT in the implementation. Or I could stick with exec parameter. What do you think?
-------------
PR: https://git.openjdk.java.net/jdk/pull/294
More information about the shenandoah-dev
mailing list