Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
<rdar://problem/6548446> TCMalloc_SystemRelease should use madvise ra…
…ther than re-mmaping span of pages

* wtf/FastMalloc.cpp:
(WTF::mergeDecommittedStates): If either of the spans has been released to the system, release the other
span as well so that the flag in the merged span is accurate.
* wtf/Platform.h:
* wtf/TCSystemAlloc.cpp: Track decommitted spans when using MADV_FREE_REUSABLE / MADV_FREE_REUSE.
(TCMalloc_SystemRelease): Use madvise with MADV_FREE_REUSABLE when it is available.
(TCMalloc_SystemCommit): Use madvise with MADV_FREE_REUSE when it is available.
* wtf/TCSystemAlloc.h:

Canonical link: https://commits.webkit.org/33719@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@41660 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
bdash committed Mar 13, 2009
1 parent f11ba3b commit 8193336
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 14 deletions.
15 changes: 15 additions & 0 deletions JavaScriptCore/ChangeLog
@@ -1,3 +1,18 @@
2009-03-12 Mark Rowe <mrowe@apple.com>

Reviewed by Darin Adler.

<rdar://problem/6548446> TCMalloc_SystemRelease should use madvise rather than re-mmaping span of pages

* wtf/FastMalloc.cpp:
(WTF::mergeDecommittedStates): If either of the spans has been released to the system, release the other
span as well so that the flag in the merged span is accurate.
* wtf/Platform.h:
* wtf/TCSystemAlloc.cpp: Track decommitted spans when using MADV_FREE_REUSABLE / MADV_FREE_REUSE.
(TCMalloc_SystemRelease): Use madvise with MADV_FREE_REUSABLE when it is available.
(TCMalloc_SystemCommit): Use madvise with MADV_FREE_REUSE when it is available.
* wtf/TCSystemAlloc.h:

2009-03-12 Adam Treat <adam.treat@torchmobile.com>

Reviewed by NOBODY (Build fix).
Expand Down
10 changes: 8 additions & 2 deletions JavaScriptCore/wtf/FastMalloc.cpp
Expand Up @@ -94,7 +94,7 @@
#define FORCE_SYSTEM_MALLOC 1
#endif

#define TCMALLOC_TRACK_DECOMMITED_SPANS (HAVE(VIRTUALALLOC))
#define TCMALLOC_TRACK_DECOMMITED_SPANS (HAVE(VIRTUALALLOC) || HAVE(MADV_FREE_REUSE))

#ifndef NDEBUG
namespace WTF {
Expand Down Expand Up @@ -1403,8 +1403,14 @@ static ALWAYS_INLINE void mergeDecommittedStates(Span*, Span*) { }
#else
static ALWAYS_INLINE void mergeDecommittedStates(Span* destination, Span* other)
{
if (other->decommitted)
if (destination->decommitted && !other->decommitted) {
TCMalloc_SystemRelease(reinterpret_cast<void*>(other->start << kPageShift),
static_cast<size_t>(other->length << kPageShift));
} else if (other->decommitted && !destination->decommitted) {
TCMalloc_SystemRelease(reinterpret_cast<void*>(destination->start << kPageShift),
static_cast<size_t>(destination->length << kPageShift));
destination->decommitted = true;
}
}
#endif

Expand Down
4 changes: 4 additions & 0 deletions JavaScriptCore/wtf/Platform.h
Expand Up @@ -348,6 +348,10 @@
#define HAVE_SYS_TIME_H 1
#define HAVE_SYS_TIMEB_H 1

#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
#define HAVE_MADV_FREE_REUSE 1
#endif

#elif PLATFORM(WIN_OS)

#define HAVE_FLOAT_H 1
Expand Down
44 changes: 34 additions & 10 deletions JavaScriptCore/wtf/TCSystemAlloc.cpp
Expand Up @@ -381,9 +381,17 @@ void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size, size_t alignment) {
return NULL;
}

#if HAVE(MADV_FREE_REUSE)

void TCMalloc_SystemRelease(void* start, size_t length)
{
while (madvise(start, length, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { }
}

#elif HAVE(MADV_DONTNEED)

void TCMalloc_SystemRelease(void* start, size_t length)
{
#if HAVE(MADV_DONTNEED)
if (FLAGS_malloc_devmem_start) {
// It's not safe to use MADV_DONTNEED if we've been mapping
// /dev/mem for heap memory
Expand Down Expand Up @@ -414,25 +422,41 @@ void TCMalloc_SystemRelease(void* start, size_t length)
errno == EAGAIN) {
// NOP
}
return;
}
#endif
}

#if HAVE(MMAP)
#elif HAVE(MMAP)

void TCMalloc_SystemRelease(void* start, size_t length)
{
void* newAddress = mmap(start, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
// If the mmap failed then that's ok, we just won't return the memory to the system.
ASSERT_UNUSED(newAddress, newAddress == start || newAddress == reinterpret_cast<void*>(MAP_FAILED));
return;
#endif
}

#else

// Platforms that don't support returning memory use an empty inline version of TCMalloc_SystemRelease
// declared in TCSystemAlloc.h

#if !HAVE(MADV_DONTNEED) && !HAVE(MMAP)
UNUSED_PARAM(start);
UNUSED_PARAM(length);
#endif

#if HAVE(MADV_FREE_REUSE)

void TCMalloc_SystemCommit(void* start, size_t length)
{
while (madvise(start, length, MADV_FREE_REUSE) == -1 && errno == EAGAIN) { }
}

#if HAVE(VIRTUALALLOC)
#elif HAVE(VIRTUALALLOC)

void TCMalloc_SystemCommit(void*, size_t)
{
}

#else

// Platforms that don't need to explicitly commit memory use an empty inline version of TCMalloc_SystemCommit
// declared in TCSystemAlloc.h

#endif
8 changes: 6 additions & 2 deletions JavaScriptCore/wtf/TCSystemAlloc.h
Expand Up @@ -62,9 +62,13 @@ extern void* TCMalloc_SystemAlloc(size_t bytes, size_t *actual_bytes,
// be released, partial pages will not.)
extern void TCMalloc_SystemRelease(void* start, size_t length);

#if HAVE(VIRTUALALLOC)
extern void TCMalloc_SystemCommit(void* start, size_t length);
#else

#if !HAVE(MADV_FREE_REUSE) && !HAVE(MADV_DONTNEED) && !HAVE(MMAP)
inline void TCMalloc_SystemRelease(void*, size_t) { }
#endif

#if !HAVE(VIRTUALALLOC) && !HAVE(MADV_FREE_REUSE)
inline void TCMalloc_SystemCommit(void*, size_t) { }
#endif

Expand Down

0 comments on commit 8193336

Please sign in to comment.