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 23, 2019
1 parent fc5712c commit 740fb79
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() = default;
jemalloc_ptr_info_s(enum PtrInfoTag aTag, void* aAddr, size_t aSize,
arena_id_t aArenaId)
: tag(aTag),
addr(aAddr),
size(aSize)
# ifdef MOZ_DEBUG
,
arenaId(aArenaId)
# endif
{
}
#endif
} jemalloc_ptr_info_t;

static inline bool jemalloc_ptr_is_live(jemalloc_ptr_info_t* info) {
Expand Down

0 comments on commit 740fb79

Please sign in to comment.