Comments (16)
Maybe the existing runtimes do by incident, I haven't checked, but you're relying on implementation detail of the runtimes.
Only some of them do that. Some of them do not. Especially when in debug builds with debug runtimes/libraries in play.
(or perhaps not bother overriding at all since they all use malloc underneath...)
This is not true. It may be true on some platforms (libstdc++ maybe) but is not true on others.
To be very clear, it is also not true to ever assume that one overload of new
will ever call a different overload of new
by default.
To do otherwise is to invoke undefined behavior.
If mimalloc is overriding new
, I would not only absolutely expect it to override all overloads, I would also expect that with mimalloc's debug/security/correctness layer turned on that mimalloc would detect and raise an error when new
and free
(or malloc
and delete
) are inappropriately paired, just like some existing C++ standard library implementations do today.
from mimalloc.
The implementations call the non-throw versions and those are overridden.
I haven't found where, in mimalloc, they are overridden.
Even stronger, for overriding to work, you don't even need to override new as that eventually invokes malloc.
First, operator new
doesn't necessarily have to call malloc
. Maybe the existing runtimes do by incident, I haven't checked, but you're relying on implementation detail of the runtimes.
Second, if you want to rely on implementation details, then at least be consistent about it. Either override all operators, or none. At least, if the operators don't use malloc
/free
, they will be able to work with whatever heap they all use.
from mimalloc.
When the standard says throw bad_alloc
then the operator should do it. It is the caller who should be able to do something about it, if he wants to. Also note that there is set_new_handler
API.
from mimalloc.
Just pushed a new commit that implements the correct overriding for new/delete if compiling with a C++ compiler; adds overrides for all current new/delete variants including nothrow
etc. When using a C compiler we cannot call get_new_handler
or throw exceptions, so in that case these are not overridden at all and we rely on the standard implementations calling malloc/free under the hood. (we do override aligned_alloc
as well so everything should work now) :-)
from mimalloc.
Hi, good suggestion. However, when I look at the standard, the default implementations refer to the throwing versions and those are overridden. So it seems to be ok to not override the nothrow_t
versions explicitly right? I would like to reduce the override API as much as possible.
from mimalloc.
If you don't override all overloads provided by the compiler runtime then those overloads are linked to the program, which means some of the overloads will call mimalloc and others - compiler runtime. You need to override all memory allocation functions, including std::nothrow_t
versions.
from mimalloc.
I'll add that the C++ standard is not really authoritative in this case as it doesn't deal with compiler implementations and ABI. And replacing memory allocations means dealing with both. You should be looking at C++ ABI documents and ABI libraries implementation to see which functions are actually called by the compiler. Plus the C/POSIX memory allocation functions.
from mimalloc.
@Lastique: If you don't override all overloads provided by the compiler runtime then those overloads are linked to the program, which means some of the overloads will call mimalloc and others - compiler runtime
I don't think that is the case. The implementations call the non-throw versions and those are overridden. Even stronger, for overriding to work, you don't even need to override new
as that eventually invokes malloc
. We override new
anyways but that is just for better performance.
You are right though if the compiler library calls itself internal versions of malloc, but in that case we are in trouble anyway since any library function (like at_exit
) might call the internal functions...
from mimalloc.
I see, it is a good argument. Also, I realized the current override of new
is not according to the specification as we don't raise a bad_alloc
exception on out-of-memory (but return NULL). Raising an exception in this case is not great though as there is nothing that can be done, calling exit
or abort
seems a better strategy. (worse, an most lazy commit systems new
never fails but an access later on might which is arguably worse than returning NULL
).
from mimalloc.
Well, of course :-) But I observed quite a speed improvement for redirecting new
so there is quite a cost to supporting this behavior. The right thing to do seems to redirect to a mi_new
function that calls the global new_handler
if it cannot allocate -- this would preserve the standard semantics and still be efficient. And than also override the no_throw
variants.
from mimalloc.
With the claim of a general usability of the library the decision for a standard-compliant behaviour should actually be easy. I am confident that mimalloc will nevertheless reach a top position in all performance comparisons.
from mimalloc.
Yes, I agree -- I will fix this soon. The best thing to do seems to override all and implementing the standard semantics. (or perhaps not bother overriding at all since they all use malloc
underneath...)
from mimalloc.
or perhaps not bother overriding at all since they all use malloc underneath... π
I also think you overestimate the importance of the operator new in modern C++ programs. Almost all dynamic memory allocations nowadays are made by standard container classes (like std::vector<>
, std::list<>
etc.) that use the std::allocator<>
class, which conceptually separates the (possible bulk) memory allocation from the construction of (separate) instances via the placement new operator.
And no, this is not a request to overwrite std::allocator<>
...
from mimalloc.
Most widespread standard libraries use operator new
/operator delete
in std::allocator
. And I wouldn't underestimate the amount of allocations beside std::allocator
. To give you a perspective, if you have std::vector<std::unique_ptr<T>>
with N elements in your code, you have one to few allocations through std::allocator
and N allocations directly via new
.
I think, if mimalloc intends to replace the standard heap, operator new
/operator delete
should be overridden.
from mimalloc.
Most widespread standard libraries use
operator new
/operator delete
in std::allocator.
Yeah, you're right. The std::allocator<> calls operator new and operator delete as functions directly. I wasn't aware of that.
However, I don't see much benefit in the overwriting as the original motivation of improved performance is hardly given anymore as soon as the operators implement the standard compliant behavior.
from mimalloc.
However, I don't see much benefit in the overwriting as the original motivation of improved performance is hardly given anymore as soon as the operators implement the standard compliant behavior.
I'm not sure I understand. If you mean operators are supposed to benefit from mimalloc overriding malloc
and friends then that is not guaranteed by the standard.
from mimalloc.
Related Issues (20)
- Test 'malloc-nomem1' failure on 32-bit architectures after v2.1.4 HOT 1
- 2.1.4 Failure build for ppc64le error: β__builtin_thread_pointerβ is not supported on this target HOT 12
- 2.1.4 and error mingw/msys2 HOT 4
- 2.1.4: build fail on centos7 HOT 7
- CMake install with namespace and add corresponding alias targets HOT 2
- Rss memory usage increase in version 2.1.4 HOT 2
- Add dllhook mode HOT 1
- oversize allocation in mi_heap_malloc_zero_aligned_at HOT 6
- Concurrency bugs that cause hanging HOT 2
- Intermittent VirtualAlloc failure while the pagefile is growing HOT 1
- Tests fail on armhf and armv7 on Alpine Linux (musl libc) since mimalloc 2.1.4 & 1.8.4 HOT 4
- [suggestion] add a comment at the declaration of `mi_arena_t` for easier custom modify HOT 1
- Can't compile v2.1.6 tag on Ubuntu 22.04.LTS HOT 3
- malloc_good_size in overrides HOT 13
- Is it ok that `ld-linux-x86-64.so.2` `Scrt1.o` `crti.o` and `crtbeginS.o` is located before `mimalloc.o` in the linker commandline when static override malloc? HOT 1
- Inconsistent output naming of `mimalloc.dll` HOT 3
- 2.1.4: crash in mi_segment_try_purge during mi_process_done HOT 2
- Misplaced count size HOT 1
- mimalloc.o not available in vcpkg
- mimalloc-redirect for aarch64? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mimalloc.