Skip to content

Commit

Permalink
Bug 1052579 - Add ability to query ArenaID to mozjemalloc_ptr_info. r…
Browse files Browse the repository at this point in the history
…=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
  • Loading branch information
Chris Martin committed Apr 2, 2019
1 parent adac65a commit 44dfdda
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 15 deletions.
20 changes: 10 additions & 10 deletions memory/build/mozjemalloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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 {
Expand Down
29 changes: 24 additions & 5 deletions memory/build/mozjemalloc_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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) {
Expand Down

0 comments on commit 44dfdda

Please sign in to comment.