Bug 1052579 - Add ability to query ArenaID to mozjemalloc_ptr_info. r=glandium

To ensure that any new JSString has its char buffer allocated in the new arena,
it is useful to be able to query a pointer and assert that it is in the
correct arena (at-least in Debug Build).

This adds the required functionality to mozjemalloc, and JSString can use it
for its new assertion in a later change.

Differential Revision: https://phabricator.services.mozilla.com/D25711
This commit is contained in:
Chris Martin 2019-04-02 03:55:06 +00:00
Родитель d580063aad
Коммит cb3f697d99
2 изменённых файлов: 34 добавлений и 15 удалений

Просмотреть файл

@ -3054,7 +3054,7 @@ inline void MozJemalloc::jemalloc_ptr_info(const void* aPtr,
// Alternatively, if the allocator is not initialized yet, the pointer
// can't be known.
if (!chunk || !malloc_initialized) {
*aInfo = {TagUnknown, nullptr, 0};
*aInfo = {TagUnknown, nullptr, 0, 0};
return;
}
@ -3071,14 +3071,14 @@ inline void MozJemalloc::jemalloc_ptr_info(const void* aPtr,
&huge)
->Search(&key);
if (node) {
*aInfo = {TagLiveHuge, node->mAddr, node->mSize};
*aInfo = {TagLiveHuge, node->mAddr, node->mSize, node->mArena->mId};
return;
}
}
// It's not a huge allocation. Check if we have a known chunk.
if (!gChunkRTree.Get(chunk)) {
*aInfo = {TagUnknown, nullptr, 0};
*aInfo = {TagUnknown, nullptr, 0, 0};
return;
}
@ -3088,7 +3088,7 @@ inline void MozJemalloc::jemalloc_ptr_info(const void* aPtr,
size_t pageind = (((uintptr_t)aPtr - (uintptr_t)chunk) >> gPageSize2Pow);
if (pageind < gChunkHeaderNumPages) {
// Within the chunk header.
*aInfo = {TagUnknown, nullptr, 0};
*aInfo = {TagUnknown, nullptr, 0, 0};
return;
}
@ -3109,7 +3109,7 @@ inline void MozJemalloc::jemalloc_ptr_info(const void* aPtr,
}
void* pageaddr = (void*)(uintptr_t(aPtr) & ~gPageSizeMask);
*aInfo = {tag, pageaddr, gPageSize};
*aInfo = {tag, pageaddr, gPageSize, chunk->arena->mId};
return;
}
@ -3129,20 +3129,20 @@ inline void MozJemalloc::jemalloc_ptr_info(const void* aPtr,
pageind--;
MOZ_DIAGNOSTIC_ASSERT(pageind >= gChunkHeaderNumPages);
if (pageind < gChunkHeaderNumPages) {
*aInfo = {TagUnknown, nullptr, 0};
*aInfo = {TagUnknown, nullptr, 0, 0};
return;
}
mapbits = chunk->map[pageind].bits;
MOZ_DIAGNOSTIC_ASSERT(mapbits & CHUNK_MAP_LARGE);
if (!(mapbits & CHUNK_MAP_LARGE)) {
*aInfo = {TagUnknown, nullptr, 0};
*aInfo = {TagUnknown, nullptr, 0, 0};
return;
}
}
void* addr = ((char*)chunk) + (pageind << gPageSize2Pow);
*aInfo = {TagLiveLarge, addr, size};
*aInfo = {TagLiveLarge, addr, size, chunk->arena->mId};
return;
}
@ -3157,7 +3157,7 @@ inline void MozJemalloc::jemalloc_ptr_info(const void* aPtr,
uintptr_t reg0_addr = (uintptr_t)run + run->mBin->mRunFirstRegionOffset;
if (aPtr < (void*)reg0_addr) {
// In the run header.
*aInfo = {TagUnknown, nullptr, 0};
*aInfo = {TagUnknown, nullptr, 0, 0};
return;
}
@ -3173,7 +3173,7 @@ inline void MozJemalloc::jemalloc_ptr_info(const void* aPtr,
PtrInfoTag tag =
((run->mRegionsMask[elm] & (1U << bit))) ? TagFreedSmall : TagLiveSmall;
*aInfo = {tag, addr, size};
*aInfo = {tag, addr, size, chunk->arena->mId};
}
namespace Debug {

Просмотреть файл

@ -94,22 +94,22 @@ typedef struct {
enum PtrInfoTag {
// The pointer is not currently known to the allocator.
// 'addr' and 'size' are always 0.
// 'addr', 'size', and 'arenaId' are always 0.
TagUnknown,
// The pointer is within a live allocation.
// 'addr' and 'size' describe the allocation.
// 'addr', 'size', and 'arenaId' describe the allocation.
TagLiveSmall,
TagLiveLarge,
TagLiveHuge,
// The pointer is within a small freed allocation.
// 'addr' and 'size' describe the allocation.
// 'addr', 'size', and 'arenaId' describe the allocation.
TagFreedSmall,
// The pointer is within a freed page. Details about the original
// allocation, including its size, are not available.
// 'addr' and 'size' describe the page.
// 'addr', 'size', and 'arenaId' describe the page.
TagFreedPageDirty,
TagFreedPageDecommitted,
TagFreedPageMadvised,
@ -121,10 +121,29 @@ enum PtrInfoTag {
// - The number of fields is minimized.
// - The 'tag' field unambiguously defines the meaning of the subsequent fields.
// Helper functions are used to group together related categories of tags.
typedef struct {
typedef struct jemalloc_ptr_info_s {
enum PtrInfoTag tag;
void* addr; // meaning depends on tag; see above
size_t size; // meaning depends on tag; see above
#ifdef MOZ_DEBUG
arena_id_t arenaId; // meaning depends on tag; see above
#endif
#ifdef __cplusplus
jemalloc_ptr_info_s() {}
jemalloc_ptr_info_s(enum PtrInfoTag tag, void* addr, size_t size,
arena_id_t arenaId)
: tag(tag),
addr(addr),
size(size)
# ifdef MOZ_DEBUG
,
arenaId(arenaId)
# endif
{
}
#endif
} jemalloc_ptr_info_t;
static inline bool jemalloc_ptr_is_live(jemalloc_ptr_info_t* info) {