RFR: 8264707: HotSpot Style Guide should permit use of lambda
Kim Barrett
kim.barrett at oracle.com
Wed Sep 8 23:25:20 UTC 2021
> On Aug 21, 2021, at 4:48 AM, Andrew Haley <aph at openjdk.java.net> wrote:
>
> So here's an oink in the flightment:
>
>
> macroAssembler_aarch64_aes.o: Error: Use of global operators new and delete is not allowed in Hotspot:
> U operator delete(void*)
> U operator new(unsigned long)
> See: /Users/aph/theRealAph-jdk/make/hotspot/lib/CompileJvm.gmk
>
>
>
> This happened on MacOS/AArch64, and was caused by an apparently innocuous Lambda. GCC doesn't generate new and delete for this construct, but AArch64 clang does for some reason. And I guess it's true that C++ compilers are free to do this, and even if one compiler doesn't do so today, it might tomorrow.
>
> What should we do? At least for my application, it doesn't matter if new and delete are used, but in some cases it might. Do we need a blanket prohibition against new and delete, when the programmer has no control over it?
Andrew sent me his failing example.
The global allocator uses are due to his code using std::function to capture a
lambda, not because of the lambda itself. std::function is not approved for
use in HotSpot code, and might never be, even if we were to start using other
parts of the standard library. (See below.)
It only happened with clang, not with gcc. That's probably because of
different implementations. Their std::function implementations might have
different SBO (Small Buffer Optimization) sizes. Or something about their
implementations of lambda might have led to different sized objects. Or code
or compiler differences might result in apparent but conditional references
that didn't get optimized away under clang under the compilation mode being
used. Or still other possibilities.
std::function *does* do allocation in many cases. And unfortunately, it
doesn’t support control of the allocator it uses. There’s API for that, but it
apparently never worked properly, gcc never even implemented it, and allocator
awareness for std::function was completely removed (not fixed or deprecated)
in C++17.
http://open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0302r0.html
So without some care, conversion from a lambda to a std::function may attempt
to invoke the default global allocator, which doesn't work in HotSpot. And we
can't use the allocator support even in C++14, since support for that feature
is either incomplete or non-existent in platforms we care about (and probably
others too). The allocation can probably be avoided by passing the lambda by
reference rather than by value, for example by
std::function<...>(std::ref(the_lambda)), as the reference will (probably) fit
in the function's expected SBO buffer, whereas the_lambda might be too big.
(Typical SBO buffer size seems to be 2-3 pointers.) There are other things to
think about here too. For example, the size of a lambda depends on what it
captures and how, so whether it's worth capturing the lambda itself by
reference or value depends on many low-level and implementation-dependent
details.
I think we will want a type-erasing callable lambda holder like std::function.
Otherwise, some use-cases end up being forced to be templates all the way
down, which is probably not great. But do we need such a thing immediately,
as part of using lambda at all? I don't think so, but that's something to
consider when deciding whether to allow using lambda in HotSpot.
Because of restrictions we're imposing on lambda usage, and in particular
requiring only downward usage, it should be possible to create such a holder
that isn't too complicated either to implement or to use, and also avoids
memory allocation. Having such a facility would also make it very easy to
implement a somewhat different form of the ScopeGuard facility provided as an
example.
Andrew wondered if there might be an ongoing problem that we don't necessarily
know whether some language feature allocates memory, now, or might in the
future. I think we can make educated guesses. I also think control of memory
allocation is a pretty important issue to a lot of C++ developers, so I would
not expect the committee or implementors to quietly add allocation points.
More information about the hotspot-dev
mailing list