summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/runtime/Collector.cpp
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-05-05 14:36:32 +0100
committerBen Murdoch <benm@google.com>2011-05-10 15:38:30 +0100
commitf05b935882198ccf7d81675736e3aeb089c5113a (patch)
tree4ea0ca838d9ef1b15cf17ddb3928efb427c7e5a1 /JavaScriptCore/runtime/Collector.cpp
parent60fbdcc62bced8db2cb1fd233cc4d1e4ea17db1b (diff)
downloadexternal_webkit-f05b935882198ccf7d81675736e3aeb089c5113a.zip
external_webkit-f05b935882198ccf7d81675736e3aeb089c5113a.tar.gz
external_webkit-f05b935882198ccf7d81675736e3aeb089c5113a.tar.bz2
Merge WebKit at r74534: Initial merge by git.
Change-Id: I6ccd1154fa1b19c2ec2a66878eb675738735f1eb
Diffstat (limited to 'JavaScriptCore/runtime/Collector.cpp')
-rw-r--r--JavaScriptCore/runtime/Collector.cpp235
1 files changed, 50 insertions, 185 deletions
diff --git a/JavaScriptCore/runtime/Collector.cpp b/JavaScriptCore/runtime/Collector.cpp
index 3fbd278..38845ce 100644
--- a/JavaScriptCore/runtime/Collector.cpp
+++ b/JavaScriptCore/runtime/Collector.cpp
@@ -171,9 +171,6 @@ void Heap::destroy()
freeBlocks();
- for (unsigned i = 0; i < m_weakGCHandlePools.size(); ++i)
- m_weakGCHandlePools[i].deallocate();
-
#if ENABLE(JSC_MULTIPLE_THREADS)
if (m_currentThreadRegistrar) {
int error = pthread_key_delete(m_currentThreadRegistrar);
@@ -187,13 +184,12 @@ void Heap::destroy()
t = next;
}
#endif
- m_blockallocator.destroy();
m_globalData = 0;
}
NEVER_INLINE CollectorBlock* Heap::allocateBlock()
{
- AlignedCollectorBlock allocation = m_blockallocator.allocate();
+ PageAllocationAligned allocation = PageAllocationAligned::allocate(BLOCK_SIZE, BLOCK_SIZE, OSAllocator::JSGCHeapPages);
CollectorBlock* block = static_cast<CollectorBlock*>(allocation.base());
if (!block)
CRASH();
@@ -211,12 +207,12 @@ NEVER_INLINE CollectorBlock* Heap::allocateBlock()
size_t numBlocks = m_heap.numBlocks;
if (m_heap.usedBlocks == numBlocks) {
- static const size_t maxNumBlocks = ULONG_MAX / sizeof(AlignedCollectorBlock) / GROWTH_FACTOR;
+ static const size_t maxNumBlocks = ULONG_MAX / sizeof(PageAllocationAligned) / GROWTH_FACTOR;
if (numBlocks > maxNumBlocks)
CRASH();
numBlocks = max(MIN_ARRAY_SIZE, numBlocks * GROWTH_FACTOR);
m_heap.numBlocks = numBlocks;
- m_heap.blocks = static_cast<AlignedCollectorBlock*>(fastRealloc(m_heap.blocks, numBlocks * sizeof(AlignedCollectorBlock)));
+ m_heap.blocks = static_cast<PageAllocationAligned*>(fastRealloc(m_heap.blocks, numBlocks * sizeof(PageAllocationAligned)));
}
m_heap.blocks[m_heap.usedBlocks++] = allocation;
@@ -239,7 +235,7 @@ NEVER_INLINE void Heap::freeBlock(size_t block)
if (m_heap.numBlocks > MIN_ARRAY_SIZE && m_heap.usedBlocks < m_heap.numBlocks / LOW_WATER_FACTOR) {
m_heap.numBlocks = m_heap.numBlocks / GROWTH_FACTOR;
- m_heap.blocks = static_cast<AlignedCollectorBlock*>(fastRealloc(m_heap.blocks, m_heap.numBlocks * sizeof(AlignedCollectorBlock)));
+ m_heap.blocks = static_cast<PageAllocationAligned*>(fastRealloc(m_heap.blocks, m_heap.numBlocks * sizeof(PageAllocationAligned)));
}
}
@@ -389,175 +385,6 @@ void Heap::shrinkBlocks(size_t neededBlocks)
m_heap.collectorBlock(i)->marked.set(HeapConstants::cellsPerBlock - 1);
}
-#if OS(WINCE)
-JS_EXPORTDATA void* g_stackBase = 0;
-
-inline bool isPageWritable(void* page)
-{
- MEMORY_BASIC_INFORMATION memoryInformation;
- DWORD result = VirtualQuery(page, &memoryInformation, sizeof(memoryInformation));
-
- // return false on error, including ptr outside memory
- if (result != sizeof(memoryInformation))
- return false;
-
- DWORD protect = memoryInformation.Protect & ~(PAGE_GUARD | PAGE_NOCACHE);
- return protect == PAGE_READWRITE
- || protect == PAGE_WRITECOPY
- || protect == PAGE_EXECUTE_READWRITE
- || protect == PAGE_EXECUTE_WRITECOPY;
-}
-
-static void* getStackBase(void* previousFrame)
-{
- // find the address of this stack frame by taking the address of a local variable
- bool isGrowingDownward;
- void* thisFrame = (void*)(&isGrowingDownward);
-
- isGrowingDownward = previousFrame < &thisFrame;
- static DWORD pageSize = 0;
- if (!pageSize) {
- SYSTEM_INFO systemInfo;
- GetSystemInfo(&systemInfo);
- pageSize = systemInfo.dwPageSize;
- }
-
- // scan all of memory starting from this frame, and return the last writeable page found
- register char* currentPage = (char*)((DWORD)thisFrame & ~(pageSize - 1));
- if (isGrowingDownward) {
- while (currentPage > 0) {
- // check for underflow
- if (currentPage >= (char*)pageSize)
- currentPage -= pageSize;
- else
- currentPage = 0;
- if (!isPageWritable(currentPage))
- return currentPage + pageSize;
- }
- return 0;
- } else {
- while (true) {
- // guaranteed to complete because isPageWritable returns false at end of memory
- currentPage += pageSize;
- if (!isPageWritable(currentPage))
- return currentPage;
- }
- }
-}
-#endif
-
-#if OS(QNX)
-static inline void *currentThreadStackBaseQNX()
-{
- static void* stackBase = 0;
- static size_t stackSize = 0;
- static pthread_t stackThread;
- pthread_t thread = pthread_self();
- if (stackBase == 0 || thread != stackThread) {
- struct _debug_thread_info threadInfo;
- memset(&threadInfo, 0, sizeof(threadInfo));
- threadInfo.tid = pthread_self();
- int fd = open("/proc/self", O_RDONLY);
- if (fd == -1) {
- LOG_ERROR("Unable to open /proc/self (errno: %d)", errno);
- return 0;
- }
- devctl(fd, DCMD_PROC_TIDSTATUS, &threadInfo, sizeof(threadInfo), 0);
- close(fd);
- stackBase = reinterpret_cast<void*>(threadInfo.stkbase);
- stackSize = threadInfo.stksize;
- ASSERT(stackBase);
- stackThread = thread;
- }
- return static_cast<char*>(stackBase) + stackSize;
-}
-#endif
-
-static inline void* currentThreadStackBase()
-{
-#if OS(DARWIN)
- pthread_t thread = pthread_self();
- return pthread_get_stackaddr_np(thread);
-#elif OS(WINDOWS) && CPU(X86) && COMPILER(MSVC)
- // offset 0x18 from the FS segment register gives a pointer to
- // the thread information block for the current thread
- NT_TIB* pTib;
- __asm {
- MOV EAX, FS:[18h]
- MOV pTib, EAX
- }
- return static_cast<void*>(pTib->StackBase);
-#elif OS(WINDOWS) && CPU(X86) && COMPILER(GCC)
- // offset 0x18 from the FS segment register gives a pointer to
- // the thread information block for the current thread
- NT_TIB* pTib;
- asm ( "movl %%fs:0x18, %0\n"
- : "=r" (pTib)
- );
- return static_cast<void*>(pTib->StackBase);
-#elif OS(WINDOWS) && CPU(X86_64)
- PNT_TIB64 pTib = reinterpret_cast<PNT_TIB64>(NtCurrentTeb());
- return reinterpret_cast<void*>(pTib->StackBase);
-#elif OS(QNX)
- AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
- MutexLocker locker(mutex);
- return currentThreadStackBaseQNX();
-#elif OS(SOLARIS)
- stack_t s;
- thr_stksegment(&s);
- return s.ss_sp;
-#elif OS(OPENBSD)
- pthread_t thread = pthread_self();
- stack_t stack;
- pthread_stackseg_np(thread, &stack);
- return stack.ss_sp;
-#elif OS(SYMBIAN)
- TThreadStackInfo info;
- RThread thread;
- thread.StackInfo(info);
- return (void*)info.iBase;
-#elif OS(HAIKU)
- thread_info threadInfo;
- get_thread_info(find_thread(NULL), &threadInfo);
- return threadInfo.stack_end;
-#elif OS(UNIX)
- AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
- MutexLocker locker(mutex);
- static void* stackBase = 0;
- static size_t stackSize = 0;
- static pthread_t stackThread;
- pthread_t thread = pthread_self();
- if (stackBase == 0 || thread != stackThread) {
- pthread_attr_t sattr;
- pthread_attr_init(&sattr);
-#if HAVE(PTHREAD_NP_H) || OS(NETBSD)
- // e.g. on FreeBSD 5.4, neundorf@kde.org
- pthread_attr_get_np(thread, &sattr);
-#else
- // FIXME: this function is non-portable; other POSIX systems may have different np alternatives
- pthread_getattr_np(thread, &sattr);
-#endif
- int rc = pthread_attr_getstack(&sattr, &stackBase, &stackSize);
- (void)rc; // FIXME: Deal with error code somehow? Seems fatal.
- ASSERT(stackBase);
- pthread_attr_destroy(&sattr);
- stackThread = thread;
- }
- return static_cast<char*>(stackBase) + stackSize;
-#elif OS(WINCE)
- AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
- MutexLocker locker(mutex);
- if (g_stackBase)
- return g_stackBase;
- else {
- int dummy;
- return getStackBase(&dummy);
- }
-#else
-#error Need a way to get the stack base on this platform
-#endif
-}
-
#if ENABLE(JSC_MULTIPLE_THREADS)
static inline PlatformThread getCurrentPlatformThread()
@@ -587,7 +414,7 @@ void Heap::registerThread()
return;
pthread_setspecific(m_currentThreadRegistrar, this);
- Heap::Thread* thread = new Heap::Thread(pthread_self(), getCurrentPlatformThread(), currentThreadStackBase());
+ Heap::Thread* thread = new Heap::Thread(pthread_self(), getCurrentPlatformThread(), m_globalData->stack().origin());
MutexLocker lock(m_registeredThreadsMutex);
@@ -654,11 +481,15 @@ static inline bool isPossibleCell(void* p)
void Heap::markConservatively(MarkStack& markStack, void* start, void* end)
{
+#if OS(WINCE)
if (start > end) {
void* tmp = start;
start = end;
end = tmp;
}
+#else
+ ASSERT(start <= end);
+#endif
ASSERT((static_cast<char*>(end) - static_cast<char*>(start)) < 0x1000000);
ASSERT(isPointerAligned(start));
@@ -685,7 +516,6 @@ void Heap::markConservatively(MarkStack& markStack, void* start, void* end)
if (m_heap.collectorBlock(block) != blockAddr)
continue;
markStack.append(reinterpret_cast<JSCell*>(xAsBits));
- markStack.drain();
}
}
}
@@ -693,10 +523,8 @@ void Heap::markConservatively(MarkStack& markStack, void* start, void* end)
void NEVER_INLINE Heap::markCurrentThreadConservativelyInternal(MarkStack& markStack)
{
- void* dummy;
- void* stackPointer = &dummy;
- void* stackBase = currentThreadStackBase();
- markConservatively(markStack, stackPointer, stackBase);
+ markConservatively(markStack, m_globalData->stack().current(), m_globalData->stack().origin());
+ markStack.drain();
}
#if COMPILER(GCC)
@@ -859,9 +687,11 @@ void Heap::markOtherThreadConservatively(MarkStack& markStack, Thread* thread)
// mark the thread's registers
markConservatively(markStack, static_cast<void*>(&regs), static_cast<void*>(reinterpret_cast<char*>(&regs) + regSize));
+ markStack.drain();
void* stackPointer = otherThreadStackPointer(regs);
markConservatively(markStack, stackPointer, thread->stackBase);
+ markStack.drain();
resumeThread(thread->platformThread);
}
@@ -920,10 +750,10 @@ WeakGCHandle* Heap::addWeakGCHandle(JSCell* ptr)
if (!weakGCHandlePool(i)->isFull())
return weakGCHandlePool(i)->allocate(ptr);
- AlignedMemory<WeakGCHandlePool::poolSize> allocation = m_weakGCHandlePoolAllocator.allocate();
+ PageAllocationAligned allocation = PageAllocationAligned::allocate(WeakGCHandlePool::poolSize, WeakGCHandlePool::poolSize, OSAllocator::JSGCHeapPages);
m_weakGCHandlePools.append(allocation);
- WeakGCHandlePool* pool = new (allocation) WeakGCHandlePool();
+ WeakGCHandlePool* pool = new (allocation.base()) WeakGCHandlePool();
return pool->allocate(ptr);
}
@@ -958,6 +788,33 @@ void Heap::markProtectedObjects(MarkStack& markStack)
}
}
+void Heap::pushTempSortVector(Vector<ValueStringPair>* tempVector)
+{
+ m_tempSortingVectors.append(tempVector);
+}
+
+void Heap::popTempSortVector(Vector<ValueStringPair>* tempVector)
+{
+ ASSERT_UNUSED(tempVector, tempVector == m_tempSortingVectors.last());
+ m_tempSortingVectors.removeLast();
+}
+
+void Heap::markTempSortVectors(MarkStack& markStack)
+{
+ typedef Vector<Vector<ValueStringPair>* > VectorOfValueStringVectors;
+
+ VectorOfValueStringVectors::iterator end = m_tempSortingVectors.end();
+ for (VectorOfValueStringVectors::iterator it = m_tempSortingVectors.begin(); it != end; ++it) {
+ Vector<ValueStringPair>* tempSortingVector = *it;
+
+ Vector<ValueStringPair>::iterator vectorEnd = tempSortingVector->end();
+ for (Vector<ValueStringPair>::iterator vectorIt = tempSortingVector->begin(); vectorIt != vectorEnd; ++vectorIt)
+ if (vectorIt->first)
+ markStack.append(vectorIt->first);
+ markStack.drain();
+ }
+}
+
void Heap::clearMarkBits()
{
for (size_t i = 0; i < m_heap.usedBlocks; ++i)
@@ -1045,6 +902,9 @@ void Heap::markRoots()
// Mark explicitly registered roots.
markProtectedObjects(markStack);
+
+ // Mark temporary vector for Array sorting
+ markTempSortVectors(markStack);
// Mark misc. other roots.
if (m_markListSet && m_markListSet->size())
@@ -1232,4 +1092,9 @@ void Heap::setActivityCallback(PassOwnPtr<GCActivityCallback> activityCallback)
m_activityCallback = activityCallback;
}
+GCActivityCallback* Heap::activityCallback()
+{
+ return m_activityCallback.get();
+}
+
} // namespace JSC