diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-11 09:43:24 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-11 09:43:24 +0200 |
commit | 1b914638db989aaa98631a1c1e02c7b2d44805d8 (patch) | |
tree | 87f4fd2c7b38db320079a5de8877890d2ca3c485 /Source/JavaScriptCore/heap | |
parent | 2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (diff) | |
download | qtwebkit-1b914638db989aaa98631a1c1e02c7b2d44805d8.tar.gz |
Imported WebKit commit 9a52e27980f47e8b0d8f8b7cc0fd7b5741bceb92 (http://svn.webkit.org/repository/webkit/trunk@116736)
New snapshot to include QDeclarative* -> QQml* build fixes
Diffstat (limited to 'Source/JavaScriptCore/heap')
-rw-r--r-- | Source/JavaScriptCore/heap/CopiedSpace.cpp | 11 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/Heap.cpp | 3 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/MarkStack.cpp | 56 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/MarkStack.h | 19 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/MarkedAllocator.cpp | 38 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/MarkedAllocator.h | 2 |
6 files changed, 85 insertions, 44 deletions
diff --git a/Source/JavaScriptCore/heap/CopiedSpace.cpp b/Source/JavaScriptCore/heap/CopiedSpace.cpp index 063ea65a2..d52c4e756 100644 --- a/Source/JavaScriptCore/heap/CopiedSpace.cpp +++ b/Source/JavaScriptCore/heap/CopiedSpace.cpp @@ -183,6 +183,9 @@ void CopiedSpace::doneCopying() CopiedBlock* block = static_cast<CopiedBlock*>(m_fromSpace->removeHead()); if (block->m_isPinned) { block->m_isPinned = false; + // We don't add the block to the toSpaceSet because it was never removed. + ASSERT(m_toSpaceSet.contains(block)); + m_toSpaceFilter.add(reinterpret_cast<Bits>(block)); m_toSpace->push(block); continue; } @@ -212,10 +215,10 @@ void CopiedSpace::doneCopying() CheckedBoolean CopiedSpace::getFreshBlock(AllocationEffort allocationEffort, CopiedBlock** outBlock) { CopiedBlock* block = 0; - if (HeapBlock* heapBlock = m_heap->blockAllocator().allocate()) - block = new (NotNull, heapBlock) CopiedBlock(heapBlock->m_allocation); - else if (allocationEffort == AllocationMustSucceed) { - if (!allocateNewBlock(&block)) { + if (allocationEffort == AllocationMustSucceed) { + if (HeapBlock* heapBlock = m_heap->blockAllocator().allocate()) + block = new (NotNull, heapBlock) CopiedBlock(heapBlock->m_allocation); + else if (!allocateNewBlock(&block)) { *outBlock = 0; ASSERT_NOT_REACHED(); return false; diff --git a/Source/JavaScriptCore/heap/Heap.cpp b/Source/JavaScriptCore/heap/Heap.cpp index d0dbc3172..d43ec1242 100644 --- a/Source/JavaScriptCore/heap/Heap.cpp +++ b/Source/JavaScriptCore/heap/Heap.cpp @@ -656,6 +656,9 @@ void Heap::markRoots(bool fullGC) visitor.doneCopying(); visitor.reset(); m_sharedData.reset(); +#if ENABLE(PARALLEL_GC) + m_sharedData.resetChildren(); +#endif m_storageSpace.doneCopying(); m_operationInProgress = NoOperation; diff --git a/Source/JavaScriptCore/heap/MarkStack.cpp b/Source/JavaScriptCore/heap/MarkStack.cpp index cf6e3513c..785444e55 100644 --- a/Source/JavaScriptCore/heap/MarkStack.cpp +++ b/Source/JavaScriptCore/heap/MarkStack.cpp @@ -36,6 +36,7 @@ #include "JSObject.h" #include "ScopeChain.h" #include "Structure.h" +#include "UString.h" #include "WriteBarrier.h" #include <wtf/MainThread.h> @@ -218,17 +219,24 @@ void MarkStackArray::stealSomeCellsFrom(MarkStackArray& other) } #if ENABLE(PARALLEL_GC) -void MarkStackThreadSharedData::markingThreadMain() +void MarkStackThreadSharedData::resetChildren() +{ + for (unsigned i = 0; i < m_slaveMarkStacks.size(); ++i) + m_slaveMarkStacks[i]->reset(); +} + +void MarkStackThreadSharedData::markingThreadMain(SlotVisitor* slotVisitor) { WTF::registerGCThread(); - SlotVisitor slotVisitor(*this); - ParallelModeEnabler enabler(slotVisitor); - slotVisitor.drainFromShared(SlotVisitor::SlaveDrain); + ParallelModeEnabler enabler(*slotVisitor); + slotVisitor->drainFromShared(SlotVisitor::SlaveDrain); + delete slotVisitor; } -void MarkStackThreadSharedData::markingThreadStartFunc(void* shared) +void MarkStackThreadSharedData::markingThreadStartFunc(void* myVisitor) { - static_cast<MarkStackThreadSharedData*>(shared)->markingThreadMain(); + SlotVisitor* slotVisitor = static_cast<SlotVisitor*>(myVisitor); + slotVisitor->sharedData().markingThreadMain(slotVisitor); } #endif @@ -241,7 +249,9 @@ MarkStackThreadSharedData::MarkStackThreadSharedData(JSGlobalData* globalData) { #if ENABLE(PARALLEL_GC) for (unsigned i = 1; i < Options::numberOfGCMarkers; ++i) { - m_markingThreads.append(createThread(markingThreadStartFunc, this, "JavaScriptCore::Marking")); + SlotVisitor* slotVisitor = new SlotVisitor(*this); + m_slaveMarkStacks.append(slotVisitor); + m_markingThreads.append(createThread(markingThreadStartFunc, slotVisitor, "JavaScriptCore::Marking")); ASSERT(m_markingThreads.last()); } #endif @@ -273,7 +283,6 @@ void MarkStackThreadSharedData::reset() #else ASSERT(m_opaqueRoots.isEmpty()); #endif - m_weakReferenceHarvesters.removeAll(); } @@ -286,6 +295,7 @@ void MarkStack::reset() #else m_opaqueRoots.clear(); #endif + m_uniqueStrings.clear(); } void MarkStack::append(ConservativeRoots& conservativeRoots) @@ -486,6 +496,34 @@ void* SlotVisitor::allocateNewSpace(void* ptr, size_t bytes) return CopiedSpace::allocateFromBlock(m_copyBlock, bytes); } +inline void MarkStack::internalAppend(JSValue* slot) +{ + ASSERT(slot); + JSValue value = *slot; + ASSERT(value); + if (!value.isCell()) + return; + + if (value.isString()) { + JSString* string = jsCast<JSString*>(value.asCell()); + if (!string->isHashConstSingleton() && string->length() > 1 && !string->isRope()) { + UniqueStringMap::AddResult addResult = m_uniqueStrings.add(string->string().impl(), value); + if (addResult.isNewEntry) + string->setHashConstSingleton(); + else { + JSValue existingJSValue = addResult.iterator->second; + if (value != existingJSValue) + jsCast<JSString*>(existingJSValue.asCell())->clearHashConstSingleton(); + *slot = existingJSValue; + return; + } + } + } + + internalAppend(value.asCell()); +} + + void SlotVisitor::copyAndAppend(void** ptr, size_t bytes, JSValue* values, unsigned length) { void* oldPtr = *ptr; @@ -499,7 +537,7 @@ void SlotVisitor::copyAndAppend(void** ptr, size_t bytes, JSValue* values, unsig newValues[i] = value; if (!value) continue; - internalAppend(value); + internalAppend(&newValues[i]); } memcpy(newPtr, oldPtr, jsValuesOffset); diff --git a/Source/JavaScriptCore/heap/MarkStack.h b/Source/JavaScriptCore/heap/MarkStack.h index 0695b1b32..48b65c069 100644 --- a/Source/JavaScriptCore/heap/MarkStack.h +++ b/Source/JavaScriptCore/heap/MarkStack.h @@ -34,12 +34,14 @@ #include "UnconditionalFinalizer.h" #include "VTableSpectrum.h" #include "WeakReferenceHarvester.h" +#include <wtf/Forward.h> #include <wtf/HashMap.h> #include <wtf/HashSet.h> #include <wtf/Vector.h> #include <wtf/Noncopyable.h> #include <wtf/OSAllocator.h> #include <wtf/PageBlock.h> +#include <wtf/text/StringHash.h> namespace JSC { @@ -171,13 +173,17 @@ namespace JSC { ~MarkStackThreadSharedData(); void reset(); - + +#if ENABLE(PARALLEL_GC) + void resetChildren(); +#endif + private: friend class MarkStack; friend class SlotVisitor; #if ENABLE(PARALLEL_GC) - void markingThreadMain(); + void markingThreadMain(SlotVisitor*); static void markingThreadStartFunc(void* heap); #endif @@ -187,6 +193,7 @@ namespace JSC { MarkStackSegmentAllocator m_segmentAllocator; Vector<ThreadIdentifier> m_markingThreads; + Vector<MarkStack*> m_slaveMarkStacks; Mutex m_markingLock; ThreadCondition m_markingCondition; @@ -221,13 +228,14 @@ namespace JSC { void addOpaqueRoot(void*); bool containsOpaqueRoot(void*); int opaqueRootCount(); - + + MarkStackThreadSharedData& sharedData() { return m_shared; } bool isEmpty() { return m_stack.isEmpty(); } void reset(); size_t visitCount() const { return m_visitCount; } - + #if ENABLE(SIMPLE_HEAP_PROFILING) VTableSpectrum m_visitedTypeCounts; #endif @@ -251,6 +259,7 @@ namespace JSC { void internalAppend(JSCell*); void internalAppend(JSValue); + void internalAppend(JSValue*); JS_EXPORT_PRIVATE void mergeOpaqueRoots(); @@ -270,6 +279,8 @@ namespace JSC { MarkStackArray m_stack; HashSet<void*> m_opaqueRoots; // Handle-owning data structures not visible to the garbage collector. + typedef HashMap<StringImpl*, JSValue> UniqueStringMap; + UniqueStringMap m_uniqueStrings; #if !ASSERT_DISABLED public: diff --git a/Source/JavaScriptCore/heap/MarkedAllocator.cpp b/Source/JavaScriptCore/heap/MarkedAllocator.cpp index b5e5fff77..01f00c376 100644 --- a/Source/JavaScriptCore/heap/MarkedAllocator.cpp +++ b/Source/JavaScriptCore/heap/MarkedAllocator.cpp @@ -68,44 +68,30 @@ void* MarkedAllocator::allocateSlowCase() if (LIKELY(result != 0)) return result; - AllocationEffort allocationEffort; - - if (m_heap->shouldCollect()) - allocationEffort = AllocationCanFail; - else - allocationEffort = AllocationMustSucceed; - - MarkedBlock* block = allocateBlock(allocationEffort); - if (block) { - addBlock(block); - void* result = tryAllocate(); - ASSERT(result); - return result; + if (m_heap->shouldCollect()) { + m_heap->collect(Heap::DoNotSweep); + + result = tryAllocate(); + if (result) + return result; } - - m_heap->collect(Heap::DoNotSweep); - - result = tryAllocate(); - - if (result) - return result; - + ASSERT(!m_heap->shouldCollect()); - addBlock(allocateBlock(AllocationMustSucceed)); - + MarkedBlock* block = allocateBlock(); + ASSERT(block); + addBlock(block); + result = tryAllocate(); ASSERT(result); return result; } -MarkedBlock* MarkedAllocator::allocateBlock(AllocationEffort allocationEffort) +MarkedBlock* MarkedAllocator::allocateBlock() { MarkedBlock* block = static_cast<MarkedBlock*>(m_heap->blockAllocator().allocate()); if (block) block = MarkedBlock::recycle(block, m_heap, m_cellSize, m_cellsNeedDestruction); - else if (allocationEffort == AllocationCanFail) - return 0; else block = MarkedBlock::create(m_heap, m_cellSize, m_cellsNeedDestruction); diff --git a/Source/JavaScriptCore/heap/MarkedAllocator.h b/Source/JavaScriptCore/heap/MarkedAllocator.h index 8ad7e925f..8b3620f08 100644 --- a/Source/JavaScriptCore/heap/MarkedAllocator.h +++ b/Source/JavaScriptCore/heap/MarkedAllocator.h @@ -41,7 +41,7 @@ private: JS_EXPORT_PRIVATE void* allocateSlowCase(); void* tryAllocate(); void* tryAllocateHelper(); - MarkedBlock* allocateBlock(AllocationEffort); + MarkedBlock* allocateBlock(); MarkedBlock::FreeList m_freeList; MarkedBlock* m_currentBlock; |