Commit 0b189b32 authored by oliver@apple.com's avatar oliver@apple.com

<rdar://problem/6050421> JavaScript register file should remap to release...

<rdar://problem/6050421> JavaScript register file should remap to release physical pages accumulated during deep recursion

Reviewed by Geoff Garen

We now track the maximum extent of the RegisterFile, and when we reach the final
return from JS (so the stack portion of the registerfile becomes empty) we see
if that extent is greater than maxExcessCapacity.  If it is we use madvise or
VirtualFree to release the physical pages that were backing the excess.

git-svn-id: svn://svn.chromium.org/blink/trunk@42842 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 25850f6c
2009-04-23 Oliver Hunt <oliver@apple.com>
Reviewed by Geoff Garen.
<rdar://problem/6050421> JavaScript register file should remap to release physical pages accumulated during deep recursion
We now track the maximum extent of the RegisterFile, and when we reach the final
return from JS (so the stack portion of the registerfile becomes empty) we see
if that extent is greater than maxExcessCapacity. If it is we use madvise or
VirtualFree to release the physical pages that were backing the excess.
* interpreter/RegisterFile.cpp:
(JSC::RegisterFile::releaseExcessCapacity):
* interpreter/RegisterFile.h:
(JSC::RegisterFile::RegisterFile):
(JSC::RegisterFile::shrink):
(JSC::RegisterFile::grow):
2009-04-23 Mark Rowe <mrowe@apple.com> 2009-04-23 Mark Rowe <mrowe@apple.com>
With great sadness and a heavy heart I switch us back from YARR to WREC in With great sadness and a heavy heart I switch us back from YARR to WREC in
...@@ -42,4 +42,17 @@ RegisterFile::~RegisterFile() ...@@ -42,4 +42,17 @@ RegisterFile::~RegisterFile()
#endif #endif
} }
void RegisterFile::releaseExcessCapacity()
{
m_maxUsed = m_start;
void* memoryToRelease = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(reinterpret_cast<char*>(m_start) + commitSize * 2 - 1) & ~(commitSize - 1));
ptrdiff_t size = reinterpret_cast<char*>(m_end) - reinterpret_cast<char*>(memoryToRelease);
#if HAVE(MMAP) && !HAVE(VIRTUALALLOC)
while (madvise(memoryToRelease, size, MADV_FREE) == -1 && errno == EAGAIN) { }
#elif HAVE(VIRTUALALLOC)
VirtualFree(memoryToRelease, size, MEM_DECOMMIT);
m_commitEnd = memoryToRelease;
#endif
}
} // namespace JSC } // namespace JSC
...@@ -114,6 +114,8 @@ namespace JSC { ...@@ -114,6 +114,8 @@ namespace JSC {
static const size_t defaultCapacity = 524288; static const size_t defaultCapacity = 524288;
static const size_t defaultMaxGlobals = 8192; static const size_t defaultMaxGlobals = 8192;
static const size_t commitSize = 1 << 14; static const size_t commitSize = 1 << 14;
// Allow 8k of excess registers before we start trying to reap the registerfile
static const ptrdiff_t maxExcessCapacity = 8 * 1024;
RegisterFile(size_t capacity = defaultCapacity, size_t maxGlobals = defaultMaxGlobals); RegisterFile(size_t capacity = defaultCapacity, size_t maxGlobals = defaultMaxGlobals);
~RegisterFile(); ~RegisterFile();
...@@ -138,12 +140,15 @@ namespace JSC { ...@@ -138,12 +140,15 @@ namespace JSC {
void markCallFrames(Heap* heap) { heap->markConservatively(m_start, m_end); } void markCallFrames(Heap* heap) { heap->markConservatively(m_start, m_end); }
private: private:
void releaseExcessCapacity();
size_t m_numGlobals; size_t m_numGlobals;
const size_t m_maxGlobals; const size_t m_maxGlobals;
Register* m_start; Register* m_start;
Register* m_end; Register* m_end;
Register* m_max; Register* m_max;
Register* m_buffer; Register* m_buffer;
Register* m_maxUsed;
#if HAVE(VIRTUALALLOC) #if HAVE(VIRTUALALLOC)
Register* m_commitEnd; Register* m_commitEnd;
#endif #endif
...@@ -185,6 +190,7 @@ namespace JSC { ...@@ -185,6 +190,7 @@ namespace JSC {
#endif #endif
m_start = m_buffer + maxGlobals; m_start = m_buffer + maxGlobals;
m_end = m_start; m_end = m_start;
m_maxUsed = m_end;
m_max = m_start + capacity; m_max = m_start + capacity;
} }
...@@ -192,6 +198,8 @@ namespace JSC { ...@@ -192,6 +198,8 @@ namespace JSC {
{ {
if (newEnd < m_end) if (newEnd < m_end)
m_end = newEnd; m_end = newEnd;
if (m_end == m_start && (m_maxUsed - m_start) > maxExcessCapacity)
releaseExcessCapacity();
} }
inline bool RegisterFile::grow(Register* newEnd) inline bool RegisterFile::grow(Register* newEnd)
...@@ -213,6 +221,9 @@ namespace JSC { ...@@ -213,6 +221,9 @@ namespace JSC {
} }
#endif #endif
if (newEnd > m_maxUsed)
m_maxUsed = newEnd;
m_end = newEnd; m_end = newEnd;
return true; return true;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment