summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/heap
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-05-11 09:43:24 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-05-11 09:43:24 +0200
commit1b914638db989aaa98631a1c1e02c7b2d44805d8 (patch)
tree87f4fd2c7b38db320079a5de8877890d2ca3c485 /Source/JavaScriptCore/heap
parent2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (diff)
downloadqtwebkit-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.cpp11
-rw-r--r--Source/JavaScriptCore/heap/Heap.cpp3
-rw-r--r--Source/JavaScriptCore/heap/MarkStack.cpp56
-rw-r--r--Source/JavaScriptCore/heap/MarkStack.h19
-rw-r--r--Source/JavaScriptCore/heap/MarkedAllocator.cpp38
-rw-r--r--Source/JavaScriptCore/heap/MarkedAllocator.h2
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;