summaryrefslogtreecommitdiff
path: root/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/RegisterFile.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/javascriptcore/JavaScriptCore/interpreter/RegisterFile.h')
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/interpreter/RegisterFile.h292
1 files changed, 0 insertions, 292 deletions
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/RegisterFile.h b/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/RegisterFile.h
deleted file mode 100644
index 49304d9..0000000
--- a/src/3rdparty/javascriptcore/JavaScriptCore/interpreter/RegisterFile.h
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RegisterFile_h
-#define RegisterFile_h
-
-#include "Collector.h"
-#include "ExecutableAllocator.h"
-#include "Register.h"
-#include <stdio.h>
-#include <wtf/Noncopyable.h>
-#include <wtf/VMTags.h>
-
-#if HAVE(MMAP)
-#include <errno.h>
-#include <sys/mman.h>
-#endif
-
-#if OS(SYMBIAN)
-#include <wtf/symbian/RegisterFileAllocatorSymbian.h>
-#endif
-
-namespace JSC {
-
-/*
- A register file is a stack of register frames. We represent a register
- frame by its offset from "base", the logical first entry in the register
- file. The bottom-most register frame's offset from base is 0.
-
- In a program where function "a" calls function "b" (global code -> a -> b),
- the register file might look like this:
-
- | global frame | call frame | call frame | spare capacity |
- -----------------------------------------------------------------------------------------------------
- | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | | | | | | <-- index in buffer
- -----------------------------------------------------------------------------------------------------
- | -3 | -2 | -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | | | | | | <-- index relative to base
- -----------------------------------------------------------------------------------------------------
- | <-globals | temps-> | <-vars | temps-> | <-vars |
- ^ ^ ^ ^
- | | | |
- buffer base (frame 0) frame 1 frame 2
-
- Since all variables, including globals, are accessed by negative offsets
- from their register frame pointers, to keep old global offsets correct, new
- globals must appear at the beginning of the register file, shifting base
- to the right.
-
- If we added one global variable to the register file depicted above, it
- would look like this:
-
- | global frame |< >
- -------------------------------> <
- | 0 | 1 | 2 | 3 | 4 | 5 |< >snip< > <-- index in buffer
- -------------------------------> <
- | -4 | -3 | -2 | -1 | 0 | 1 |< > <-- index relative to base
- -------------------------------> <
- | <-globals | temps-> |
- ^ ^
- | |
- buffer base (frame 0)
-
- As you can see, global offsets relative to base have stayed constant,
- but base itself has moved. To keep up with possible changes to base,
- clients keep an indirect pointer, so their calculations update
- automatically when base changes.
-
- For client simplicity, the RegisterFile measures size and capacity from
- "base", not "buffer".
-*/
-
- class JSGlobalObject;
-
- class RegisterFile : public Noncopyable {
- friend class JIT;
- public:
- enum CallFrameHeaderEntry {
- CallFrameHeaderSize = 8,
-
- CodeBlock = -8,
- ScopeChain = -7,
- CallerFrame = -6,
- ReturnPC = -5, // This is either an Instruction* or a pointer into JIT generated code stored as an Instruction*.
- ReturnValueRegister = -4,
- ArgumentCount = -3,
- Callee = -2,
- OptionalCalleeArguments = -1
- };
-
- enum { ProgramCodeThisRegister = -CallFrameHeaderSize - 1 };
- enum { ArgumentsRegister = 0 };
-
- 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();
-
- Register* start() const { return m_start; }
- Register* end() const { return m_end; }
- size_t size() const { return m_end - m_start; }
-
- void setGlobalObject(JSGlobalObject* globalObject) { m_globalObject = globalObject; }
- JSGlobalObject* globalObject() { return m_globalObject; }
-
- bool grow(Register* newEnd);
- void shrink(Register* newEnd);
-
- void setNumGlobals(size_t numGlobals) { m_numGlobals = numGlobals; }
- int numGlobals() const { return m_numGlobals; }
- size_t maxGlobals() const { return m_maxGlobals; }
-
- Register* lastGlobal() const { return m_start - m_numGlobals; }
-
- void markGlobals(MarkStack& markStack, Heap* heap) { heap->markConservatively(markStack, lastGlobal(), m_start); }
- void markCallFrames(MarkStack& markStack, Heap* heap) { heap->markConservatively(markStack, 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
-#if OS(SYMBIAN)
- // Commits and frees a continguous chunk of memory as required
- WTF::RegisterFileAllocator* m_registerFileAllocator;
-#endif
-
- 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.
- // This is still a hack that should be fixed later. We know that a Symbian page size is 4K.
- #if OS(SYMBIAN)
- inline bool isPageAligned(size_t size) { return size && !(size % (4 * 1024)); }
- #else
- inline bool isPageAligned(size_t size) { return size && !(size % (8 * 1024)); }
- #endif
-
- inline RegisterFile::RegisterFile(size_t capacity, size_t maxGlobals)
- : m_numGlobals(0)
- , m_maxGlobals(maxGlobals)
- , m_start(0)
- , m_end(0)
- , m_max(0)
- , 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 = reinterpret_cast<Register*>(mmap(0, bufferLength, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, VM_TAG_FOR_REGISTERFILE_MEMORY, 0));
- if (m_buffer == MAP_FAILED) {
-#if OS(WINCE)
- fprintf(stderr, "Could not allocate register file: %d\n", GetLastError());
-#else
- fprintf(stderr, "Could not allocate register file: %d\n", errno);
-#endif
- CRASH();
- }
- #elif HAVE(VIRTUALALLOC)
- m_buffer = static_cast<Register*>(VirtualAlloc(0, roundUpAllocationSize(bufferLength, commitSize), MEM_RESERVE, PAGE_READWRITE));
- if (!m_buffer) {
-#if OS(WINCE)
- fprintf(stderr, "Could not allocate register file: %d\n", GetLastError());
-#else
- fprintf(stderr, "Could not allocate register file: %d\n", errno);
-#endif
- CRASH();
- }
- size_t committedSize = roundUpAllocationSize(maxGlobals * sizeof(Register), commitSize);
- void* commitCheck = VirtualAlloc(m_buffer, committedSize, MEM_COMMIT, PAGE_READWRITE);
- if (commitCheck != m_buffer) {
-#if OS(WINCE)
- fprintf(stderr, "Could not allocate register file: %d\n", GetLastError());
-#else
- fprintf(stderr, "Could not allocate register file: %d\n", errno);
-#endif
- CRASH();
- }
- m_commitEnd = reinterpret_cast<Register*>(reinterpret_cast<char*>(m_buffer) + committedSize);
- #elif OS(SYMBIAN)
- m_registerFileAllocator = new WTF::RegisterFileAllocator(bufferLength);
- m_buffer = (Register*)(m_registerFileAllocator->buffer());
- // start by committing enough space to hold maxGlobals
- void* newEnd = (void*)((int)m_buffer + (maxGlobals * sizeof(Register)));
- m_registerFileAllocator->grow(newEnd);
- #else
- /*
- * If neither MMAP nor VIRTUALALLOC are available - use fastMalloc instead.
- *
- * Please note that this is the fallback case, which is non-optimal.
- * If any possible, the platform should provide for a better memory
- * allocation mechanism that allows for "lazy commit" or dynamic
- * pre-allocation, similar to mmap or VirtualAlloc, to avoid waste of memory.
- */
- m_buffer = static_cast<Register*>(fastMalloc(bufferLength));
- #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)
- return;
- m_end = newEnd;
- if (m_end == m_start && (m_maxUsed - m_start) > maxExcessCapacity) {
-#if OS(SYMBIAN)
- m_registerFileAllocator->shrink(newEnd);
-#endif
-
- releaseExcessCapacity();
- }
- }
-
- inline bool RegisterFile::grow(Register* newEnd)
- {
- if (newEnd < m_end)
- return true;
-
- if (newEnd > m_max)
- return false;
-
-#if !HAVE(MMAP) && HAVE(VIRTUALALLOC)
- if (newEnd > m_commitEnd) {
- size_t size = roundUpAllocationSize(reinterpret_cast<char*>(newEnd) - reinterpret_cast<char*>(m_commitEnd), commitSize);
- if (!VirtualAlloc(m_commitEnd, size, MEM_COMMIT, PAGE_READWRITE)) {
-#if OS(WINCE)
- fprintf(stderr, "Could not allocate register file: %d\n", GetLastError());
-#else
- fprintf(stderr, "Could not allocate register file: %d\n", errno);
-#endif
- CRASH();
- }
- m_commitEnd = reinterpret_cast<Register*>(reinterpret_cast<char*>(m_commitEnd) + size);
- }
-#endif
-#if OS(SYMBIAN)
- m_registerFileAllocator->grow((void*)newEnd);
-#endif
-
- if (newEnd > m_maxUsed)
- m_maxUsed = newEnd;
-
- m_end = newEnd;
- return true;
- }
-
-} // namespace JSC
-
-#endif // RegisterFile_h