diff options
Diffstat (limited to 'JavaScriptCore/interpreter/RegisterFile.h')
-rw-r--r-- | JavaScriptCore/interpreter/RegisterFile.h | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/JavaScriptCore/interpreter/RegisterFile.h b/JavaScriptCore/interpreter/RegisterFile.h index c320f04..09a3963 100644 --- a/JavaScriptCore/interpreter/RegisterFile.h +++ b/JavaScriptCore/interpreter/RegisterFile.h @@ -29,10 +29,11 @@ #ifndef RegisterFile_h #define RegisterFile_h +#include "Collector.h" #include "ExecutableAllocator.h" #include "Register.h" -#include "Collector.h" #include <wtf/Noncopyable.h> +#include <wtf/VMTags.h> #if HAVE(MMAP) #include <errno.h> @@ -113,6 +114,8 @@ namespace JSC { static const size_t defaultCapacity = 524288; static const size_t defaultMaxGlobals = 8192; 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(); @@ -137,12 +140,15 @@ namespace JSC { void markCallFrames(Heap* heap) { heap->markConservatively(m_start, m_end); } private: + void releaseExcessCapacity(); size_t m_numGlobals; const size_t m_maxGlobals; Register* m_start; Register* m_end; Register* m_max; Register* m_buffer; + Register* m_maxUsed; + #if HAVE(VIRTUALALLOC) Register* m_commitEnd; #endif @@ -150,6 +156,9 @@ namespace JSC { JSGlobalObject* m_globalObject; // The global object whose vars are currently stored in the register file. }; + // FIXME: Add a generic getpagesize() to WTF, then move this function to WTF as well. + inline bool isPageAligned(size_t size) { return size != 0 && size % (8 * 1024) == 0; } + inline RegisterFile::RegisterFile(size_t capacity, size_t maxGlobals) : m_numGlobals(0) , m_maxGlobals(maxGlobals) @@ -159,9 +168,13 @@ namespace JSC { , m_buffer(0) , m_globalObject(0) { + // Verify that our values will play nice with mmap and VirtualAlloc. + ASSERT(isPageAligned(maxGlobals)); + ASSERT(isPageAligned(capacity)); + size_t bufferLength = (capacity + maxGlobals) * sizeof(Register); #if HAVE(MMAP) - m_buffer = static_cast<Register*>(mmap(0, bufferLength, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0)); + m_buffer = static_cast<Register*>(mmap(0, bufferLength, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, VM_TAG_FOR_REGISTERFILE_MEMORY, 0)); if (m_buffer == MAP_FAILED) { fprintf(stderr, "Could not allocate register file: %d\n", errno); CRASH(); @@ -184,13 +197,17 @@ namespace JSC { #endif m_start = m_buffer + maxGlobals; m_end = m_start; + m_maxUsed = m_end; m_max = m_start + capacity; } inline void RegisterFile::shrink(Register* newEnd) { - if (newEnd < m_end) - m_end = newEnd; + if (newEnd >= m_end) + return; + m_end = newEnd; + if (m_end == m_start && (m_maxUsed - m_start) > maxExcessCapacity) + releaseExcessCapacity(); } inline bool RegisterFile::grow(Register* newEnd) @@ -212,6 +229,9 @@ namespace JSC { } #endif + if (newEnd > m_maxUsed) + m_maxUsed = newEnd; + m_end = newEnd; return true; } |