diff options
author | Ben Murdoch <benm@google.com> | 2010-08-11 14:44:44 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2010-08-12 19:15:41 +0100 |
commit | dd8bb3de4f353a81954234999f1fea748aee2ea9 (patch) | |
tree | 729b52bf09294f0d6c67cd5ea80aee1b727b7bd8 /JavaScriptCore/interpreter | |
parent | f3d41ba51d86bf719c7a65ab5297aea3c17e2d98 (diff) | |
download | external_webkit-dd8bb3de4f353a81954234999f1fea748aee2ea9.zip external_webkit-dd8bb3de4f353a81954234999f1fea748aee2ea9.tar.gz external_webkit-dd8bb3de4f353a81954234999f1fea748aee2ea9.tar.bz2 |
Merge WebKit at r65072 : Initial merge by git.
Change-Id: Ibcf418498376b2660aacb7f8d46ea7085ef91585
Diffstat (limited to 'JavaScriptCore/interpreter')
-rw-r--r-- | JavaScriptCore/interpreter/Interpreter.cpp | 48 | ||||
-rw-r--r-- | JavaScriptCore/interpreter/RegisterFile.cpp | 19 | ||||
-rw-r--r-- | JavaScriptCore/interpreter/RegisterFile.h | 97 |
3 files changed, 54 insertions, 110 deletions
diff --git a/JavaScriptCore/interpreter/Interpreter.cpp b/JavaScriptCore/interpreter/Interpreter.cpp index 2342ed6..e7ae540 100644 --- a/JavaScriptCore/interpreter/Interpreter.cpp +++ b/JavaScriptCore/interpreter/Interpreter.cpp @@ -144,28 +144,28 @@ NEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vP NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue) { int dst = vPC[1].u.operand; - JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(vPC[2].u.jsCell); + CodeBlock* codeBlock = callFrame->codeBlock(); + JSGlobalObject* globalObject = codeBlock->globalObject(); ASSERT(globalObject->isGlobalObject()); - int property = vPC[3].u.operand; - Structure* structure = vPC[4].u.structure; - int offset = vPC[5].u.operand; + int property = vPC[2].u.operand; + Structure* structure = vPC[3].u.structure; + int offset = vPC[4].u.operand; if (structure == globalObject->structure()) { callFrame->r(dst) = JSValue(globalObject->getDirectOffset(offset)); return true; } - CodeBlock* codeBlock = callFrame->codeBlock(); Identifier& ident = codeBlock->identifier(property); PropertySlot slot(globalObject); if (globalObject->getPropertySlot(callFrame, ident, slot)) { JSValue result = slot.getValue(callFrame, ident); if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) { - if (vPC[4].u.structure) - vPC[4].u.structure->deref(); + if (vPC[3].u.structure) + vPC[3].u.structure->deref(); globalObject->structure()->ref(); - vPC[4] = globalObject->structure(); - vPC[5] = slot.cachedOffset(); + vPC[3] = globalObject->structure(); + vPC[4] = slot.cachedOffset(); callFrame->r(dst) = JSValue(result); return true; } @@ -184,13 +184,13 @@ NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction* NEVER_INLINE bool Interpreter::resolveGlobalDynamic(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue) { int dst = vPC[1].u.operand; - JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(vPC[2].u.jsCell); - ASSERT(globalObject->isGlobalObject()); - int property = vPC[3].u.operand; - Structure* structure = vPC[4].u.structure; - int offset = vPC[5].u.operand; CodeBlock* codeBlock = callFrame->codeBlock(); - int skip = vPC[6].u.operand; + JSGlobalObject* globalObject = codeBlock->globalObject(); + ASSERT(globalObject->isGlobalObject()); + int property = vPC[2].u.operand; + Structure* structure = vPC[3].u.structure; + int offset = vPC[4].u.operand; + int skip = vPC[5].u.operand; ScopeChainNode* scopeChain = callFrame->scopeChain(); ScopeChainIterator iter = scopeChain->begin(); @@ -231,11 +231,11 @@ NEVER_INLINE bool Interpreter::resolveGlobalDynamic(CallFrame* callFrame, Instru if (globalObject->getPropertySlot(callFrame, ident, slot)) { JSValue result = slot.getValue(callFrame, ident); if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) { - if (vPC[4].u.structure) - vPC[4].u.structure->deref(); + if (vPC[3].u.structure) + vPC[3].u.structure->deref(); globalObject->structure()->ref(); - vPC[4] = globalObject->structure(); - vPC[5] = slot.cachedOffset(); + vPC[3] = globalObject->structure(); + vPC[4] = slot.cachedOffset(); callFrame->r(dst) = JSValue(result); return true; } @@ -2284,9 +2284,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Gets the global var at global slot index and places it in register dst. */ int dst = vPC[1].u.operand; - JSGlobalObject* scope = static_cast<JSGlobalObject*>(vPC[2].u.jsCell); + JSGlobalObject* scope = codeBlock->globalObject(); ASSERT(scope->isGlobalObject()); - int index = vPC[3].u.operand; + int index = vPC[2].u.operand; callFrame->r(dst) = scope->registerAt(index); vPC += OPCODE_LENGTH(op_get_global_var); @@ -2297,10 +2297,10 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi Puts value into global slot index. */ - JSGlobalObject* scope = static_cast<JSGlobalObject*>(vPC[1].u.jsCell); + JSGlobalObject* scope = codeBlock->globalObject(); ASSERT(scope->isGlobalObject()); - int index = vPC[2].u.operand; - int value = vPC[3].u.operand; + int index = vPC[1].u.operand; + int value = vPC[2].u.operand; scope->registerAt(index) = JSValue(callFrame->r(value).jsValue()); vPC += OPCODE_LENGTH(op_put_global_var); diff --git a/JavaScriptCore/interpreter/RegisterFile.cpp b/JavaScriptCore/interpreter/RegisterFile.cpp index 63ea5b3..4f5d1d5 100644 --- a/JavaScriptCore/interpreter/RegisterFile.cpp +++ b/JavaScriptCore/interpreter/RegisterFile.cpp @@ -35,26 +35,15 @@ namespace JSC { RegisterFile::~RegisterFile() { -#if HAVE(MMAP) - munmap(m_buffer, ((m_max - m_start) + m_maxGlobals) * sizeof(Register)); -#elif HAVE(VIRTUALALLOC) -#if OS(WINCE) - VirtualFree(m_buffer, DWORD(m_commitEnd) - DWORD(m_buffer), MEM_DECOMMIT); -#endif - VirtualFree(m_buffer, 0, MEM_RELEASE); -#else - fastFree(m_buffer); -#endif + void* base = m_reservation.base(); + m_reservation.decommit(base, reinterpret_cast<intptr_t>(m_commitEnd) - reinterpret_cast<intptr_t>(base)); + m_reservation.deallocate(); } void RegisterFile::releaseExcessCapacity() { -#if HAVE(MMAP) && HAVE(MADV_FREE) && !HAVE(VIRTUALALLOC) - while (madvise(m_start, (m_max - m_start) * sizeof(Register), MADV_FREE) == -1 && errno == EAGAIN) { } -#elif HAVE(VIRTUALALLOC) - VirtualFree(m_start, (m_max - m_start) * sizeof(Register), MEM_DECOMMIT); + m_reservation.decommit(m_start, reinterpret_cast<intptr_t>(m_commitEnd) - reinterpret_cast<intptr_t>(m_start)); m_commitEnd = m_start; -#endif m_maxUsed = m_start; } diff --git a/JavaScriptCore/interpreter/RegisterFile.h b/JavaScriptCore/interpreter/RegisterFile.h index e9b8204..6c4e969 100644 --- a/JavaScriptCore/interpreter/RegisterFile.h +++ b/JavaScriptCore/interpreter/RegisterFile.h @@ -35,13 +35,9 @@ #include "WeakGCPtr.h" #include <stdio.h> #include <wtf/Noncopyable.h> +#include <wtf/PageReservation.h> #include <wtf/VMTags.h> -#if HAVE(MMAP) -#include <errno.h> -#include <sys/mman.h> -#endif - namespace JSC { /* @@ -109,9 +105,9 @@ namespace JSC { enum { ProgramCodeThisRegister = -CallFrameHeaderSize - 1 }; - static const size_t defaultCapacity = 524288; - static const size_t defaultMaxGlobals = 8192; - static const size_t commitSize = 1 << 14; + static const size_t defaultCapacity = 512 * 1024; + static const size_t defaultMaxGlobals = 8 * 1024; + static const size_t commitSize = 16 * 1024; // Allow 8k of excess registers before we start trying to reap the registerfile static const ptrdiff_t maxExcessCapacity = 8 * 1024; @@ -139,81 +135,39 @@ namespace JSC { void markCallFrames(MarkStack& markStack, Heap* heap) { heap->markConservatively(markStack, m_start, m_end); } private: + void checkAllocatedOkay(bool okay); + 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 + PageReservation m_reservation; WeakGCPtr<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) , m_start(0) , m_end(0) , m_max(0) - , m_buffer(0) { - // Verify that our values will play nice with mmap and VirtualAlloc. - ASSERT(isPageAligned(maxGlobals)); - ASSERT(isPageAligned(capacity)); + ASSERT(maxGlobals && PageAllocation::isPageAligned(maxGlobals)); + ASSERT(capacity && PageAllocation::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, 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(); - } + m_reservation = PageReservation::reserve(roundUpAllocationSize(bufferLength, commitSize), PageAllocation::JSVMStackPages); + void* base = m_reservation.base(); + checkAllocatedOkay(base); 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); - #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; + checkAllocatedOkay(m_reservation.commit(base, committedSize)); + m_commitEnd = reinterpret_cast<Register*>(reinterpret_cast<char*>(base) + committedSize); + m_start = static_cast<Register*>(base) + maxGlobals; m_end = m_start; m_maxUsed = m_end; m_max = m_start + capacity; @@ -236,20 +190,11 @@ namespace JSC { 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(); - } + checkAllocatedOkay(m_reservation.commit(m_commitEnd, size)); m_commitEnd = reinterpret_cast<Register*>(reinterpret_cast<char*>(m_commitEnd) + size); } -#endif if (newEnd > m_maxUsed) m_maxUsed = newEnd; @@ -258,6 +203,16 @@ namespace JSC { return true; } + inline void RegisterFile::checkAllocatedOkay(bool okay) + { + if (!okay) { +#ifndef NDEBUG + fprintf(stderr, "Could not allocate register file: %d\n", PageReservation::lastError()); +#endif + CRASH(); + } + } + } // namespace JSC #endif // RegisterFile_h |