mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 23:34:52 +02:00
8297718: Make NMT free:ing protocol more granular
Reviewed-by: stuefe, gziemski
This commit is contained in:
parent
fbe7b00738
commit
165dcdd27d
7 changed files with 72 additions and 25 deletions
|
@ -62,6 +62,7 @@
|
|||
#include "runtime/vm_version.hpp"
|
||||
#include "services/attachListener.hpp"
|
||||
#include "services/mallocTracker.hpp"
|
||||
#include "services/mallocHeader.inline.hpp"
|
||||
#include "services/memTracker.hpp"
|
||||
#include "services/nmtPreInit.hpp"
|
||||
#include "services/nmtCommon.hpp"
|
||||
|
@ -714,30 +715,31 @@ void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, const NativeCa
|
|||
return NULL;
|
||||
}
|
||||
|
||||
const size_t old_size = MallocTracker::malloc_header(memblock)->size();
|
||||
|
||||
// De-account the old block from NMT *before* calling the real realloc(3) since it
|
||||
// may invalidate old block including its header. This will also perform integrity checks
|
||||
// on the old block (e.g. overwriters) and mark the old header as dead.
|
||||
void* const old_outer_ptr = MemTracker::record_free(memblock);
|
||||
// Perform integrity checks on and mark the old block as dead *before* calling the real realloc(3) since it
|
||||
// may invalidate the old block, including its header.
|
||||
MallocHeader* header = MallocTracker::malloc_header(memblock);
|
||||
header->assert_block_integrity(); // Assert block hasn't been tampered with.
|
||||
const MallocHeader::FreeInfo free_info = header->free_info();
|
||||
header->mark_block_as_dead();
|
||||
|
||||
// the real realloc
|
||||
ALLOW_C_FUNCTION(::realloc, void* const new_outer_ptr = ::realloc(old_outer_ptr, new_outer_size);)
|
||||
ALLOW_C_FUNCTION(::realloc, void* const new_outer_ptr = ::realloc(header, new_outer_size);)
|
||||
|
||||
if (new_outer_ptr == NULL) {
|
||||
// If realloc(3) failed, the old block still exists. We must re-instantiate the old
|
||||
// NMT header then, since we marked it dead already. Otherwise subsequent os::realloc()
|
||||
// or os::free() calls would trigger block integrity asserts.
|
||||
void* p = MemTracker::record_malloc(old_outer_ptr, old_size, memflags, stack);
|
||||
assert(p == memblock, "sanity");
|
||||
return NULL;
|
||||
// realloc(3) failed and the block still exists.
|
||||
// We have however marked it as dead, revert this change.
|
||||
header->revive();
|
||||
return nullptr;
|
||||
}
|
||||
// realloc(3) succeeded, variable header now points to invalid memory and we need to deaccount the old block.
|
||||
MemTracker::deaccount(free_info);
|
||||
|
||||
// After a successful realloc(3), we re-account the resized block with its new size
|
||||
// to NMT. This re-instantiates the NMT header.
|
||||
// After a successful realloc(3), we account the resized block with its new size
|
||||
// to NMT.
|
||||
void* const new_inner_ptr = MemTracker::record_malloc(new_outer_ptr, size, memflags, stack);
|
||||
|
||||
#ifdef ASSERT
|
||||
size_t old_size = free_info.size;
|
||||
if (old_size < size) {
|
||||
// We also zap the newly extended region.
|
||||
::memset((char*)new_inner_ptr + old_size, uninitBlockPad, size - old_size);
|
||||
|
@ -774,7 +776,7 @@ void os::free(void *memblock) {
|
|||
|
||||
DEBUG_ONLY(break_if_ptr_caught(memblock);)
|
||||
|
||||
// If NMT is enabled, this checks for heap overwrites, then de-accounts the old block.
|
||||
// When NMT is enabled this checks for heap overwrites, then deaccounts the old block.
|
||||
void* const old_outer_ptr = MemTracker::record_free(memblock);
|
||||
|
||||
ALLOW_C_FUNCTION(::free, ::free(old_outer_ptr);)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue