summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/interpreter
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2010-08-11 14:44:44 +0100
committerBen Murdoch <benm@google.com>2010-08-12 19:15:41 +0100
commitdd8bb3de4f353a81954234999f1fea748aee2ea9 (patch)
tree729b52bf09294f0d6c67cd5ea80aee1b727b7bd8 /JavaScriptCore/interpreter
parentf3d41ba51d86bf719c7a65ab5297aea3c17e2d98 (diff)
downloadexternal_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.cpp48
-rw-r--r--JavaScriptCore/interpreter/RegisterFile.cpp19
-rw-r--r--JavaScriptCore/interpreter/RegisterFile.h97
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