diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-09-10 19:10:20 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-09-10 19:10:20 +0200 |
commit | 284837daa07b29d6a63a748544a90b1f5842ac5c (patch) | |
tree | ecd258180bde91fe741e0cfd2638beb3c6da7e8e /Source/JavaScriptCore/heap | |
parent | 2e2ba8ff45915f40ed3e014101269c175f2a89a0 (diff) | |
download | qtwebkit-284837daa07b29d6a63a748544a90b1f5842ac5c.tar.gz |
Imported WebKit commit 68645295d2e3e09af2c942f092556f06aa5f8b0d (http://svn.webkit.org/repository/webkit/trunk@128073)
New snapshot
Diffstat (limited to 'Source/JavaScriptCore/heap')
-rw-r--r-- | Source/JavaScriptCore/heap/Handle.h | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/Heap.cpp | 48 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/Heap.h | 6 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/HeapTimer.cpp | 6 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/IncrementalSweeper.cpp | 48 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/IncrementalSweeper.h | 4 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/JITStubRoutineSet.cpp | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/MachineStackMarker.cpp | 1 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/MarkStack.cpp | 5 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/MarkStackInlineMethods.h | 8 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/MarkedBlock.cpp | 4 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/MarkedBlock.h | 18 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/MarkedSpace.cpp | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/WeakBlock.cpp | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/WeakSet.cpp | 3 | ||||
-rw-r--r-- | Source/JavaScriptCore/heap/WeakSet.h | 13 |
16 files changed, 137 insertions, 35 deletions
diff --git a/Source/JavaScriptCore/heap/Handle.h b/Source/JavaScriptCore/heap/Handle.h index 62f267e12..3b62e2054 100644 --- a/Source/JavaScriptCore/heap/Handle.h +++ b/Source/JavaScriptCore/heap/Handle.h @@ -102,7 +102,7 @@ template <typename Base> struct HandleConverter<Base, Unknown> { Handle<JSObject> asObject() const; bool isObject() const { return jsValue().isObject(); } bool getNumber(double number) const { return jsValue().getNumber(number); } - UString getString(ExecState*) const; + WTF::String getString(ExecState*) const; bool isUndefinedOrNull() const { return jsValue().isUndefinedOrNull(); } private: diff --git a/Source/JavaScriptCore/heap/Heap.cpp b/Source/JavaScriptCore/heap/Heap.cpp index 669178804..4ab8ccb31 100644 --- a/Source/JavaScriptCore/heap/Heap.cpp +++ b/Source/JavaScriptCore/heap/Heap.cpp @@ -753,6 +753,9 @@ void Heap::collect(SweepToggle sweepToggle) m_objectSpace.resetAllocators(); } + if (Options::useZombieMode()) + zombifyDeadObjects(); + size_t currentHeapSize = size(); if (fullGC) { m_sizeAfterLastCollect = currentHeapSize; @@ -844,4 +847,49 @@ void Heap::didStartVMShutdown() lastChanceToFinalize(); } +class ZombifyCellFunctor : public MarkedBlock::VoidFunctor { +public: + ZombifyCellFunctor(size_t cellSize) + : m_cellSize(cellSize) + { + } + + void operator()(JSCell* cell) + { + if (Options::zombiesAreImmortal()) + MarkedBlock::blockFor(cell)->setMarked(cell); + + void** current = reinterpret_cast<void**>(cell); + + // We want to maintain zapped-ness because that's how we know if we've called + // the destructor. + if (cell->isZapped()) + current++; + + void* limit = static_cast<void*>(reinterpret_cast<char*>(cell) + m_cellSize); + for (; current < limit; current++) + *current = reinterpret_cast<void*>(0xbbadbeef); + } + +private: + size_t m_cellSize; +}; + +class ZombifyBlockFunctor : public MarkedBlock::VoidFunctor { +public: + void operator()(MarkedBlock* block) + { + ZombifyCellFunctor functor(block->cellSize()); + block->forEachDeadCell(functor); + } +}; + +void Heap::zombifyDeadObjects() +{ + m_objectSpace.sweep(); + + ZombifyBlockFunctor functor; + m_objectSpace.forEachBlock(functor); +} + } // namespace JSC diff --git a/Source/JavaScriptCore/heap/Heap.h b/Source/JavaScriptCore/heap/Heap.h index 6f13afb72..69aa97e33 100644 --- a/Source/JavaScriptCore/heap/Heap.h +++ b/Source/JavaScriptCore/heap/Heap.h @@ -59,11 +59,10 @@ namespace JSC { class LLIntOffsetsExtractor; class MarkedArgumentBuffer; class RegisterFile; - class UString; class WeakGCHandlePool; class SlotVisitor; - typedef std::pair<JSValue, UString> ValueStringPair; + typedef std::pair<JSValue, WTF::String> ValueStringPair; typedef HashCountedSet<JSCell*> ProtectCountSet; typedef HashCountedSet<const char*> TypeCountSet; @@ -204,7 +203,8 @@ namespace JSC { void harvestWeakReferences(); void finalizeUnconditionalFinalizers(); void deleteUnmarkedCompiledCode(); - + void zombifyDeadObjects(); + RegisterFile& registerFile(); BlockAllocator& blockAllocator(); diff --git a/Source/JavaScriptCore/heap/HeapTimer.cpp b/Source/JavaScriptCore/heap/HeapTimer.cpp index fa979781e..214f86757 100644 --- a/Source/JavaScriptCore/heap/HeapTimer.cpp +++ b/Source/JavaScriptCore/heap/HeapTimer.cpp @@ -29,7 +29,8 @@ #include "APIShims.h" #include "JSObject.h" #include "JSString.h" -#include "ScopeChain.h" + +#include <wtf/MainThread.h> #include <wtf/Threading.h> namespace JSC { @@ -104,6 +105,9 @@ HeapTimer::HeapTimer(JSGlobalData* globalData) : m_globalData(globalData) , m_timer(this, &HeapTimer::timerDidFire) { + // FIXME: Implement HeapTimer for other threads. + if (WTF::isMainThread() && !m_timer.tryCreateClient()) + CRASH(); } HeapTimer::~HeapTimer() diff --git a/Source/JavaScriptCore/heap/IncrementalSweeper.cpp b/Source/JavaScriptCore/heap/IncrementalSweeper.cpp index f284d8b57..bd1342f2a 100644 --- a/Source/JavaScriptCore/heap/IncrementalSweeper.cpp +++ b/Source/JavaScriptCore/heap/IncrementalSweeper.cpp @@ -31,22 +31,19 @@ #include "JSObject.h" #include "JSString.h" #include "MarkedBlock.h" -#include "ScopeChain.h" + #include <wtf/HashSet.h> #include <wtf/WTFThreadData.h> namespace JSC { -#if USE(CF) +#if USE(CF) || PLATFORM(BLACKBERRY) -static const CFTimeInterval sweepTimeSlice = .01; // seconds -static const CFTimeInterval sweepTimeTotal = .10; -static const CFTimeInterval sweepTimeMultiplier = 1.0 / sweepTimeTotal; +static const double sweepTimeSlice = .01; // seconds +static const double sweepTimeTotal = .10; +static const double sweepTimeMultiplier = 1.0 / sweepTimeTotal; -void IncrementalSweeper::doWork() -{ - doSweep(WTF::monotonicallyIncreasingTime()); -} +#if USE(CF) IncrementalSweeper::IncrementalSweeper(Heap* heap, CFRunLoopRef runLoop) : HeapTimer(heap->globalData(), runLoop) @@ -70,12 +67,43 @@ void IncrementalSweeper::cancelTimer() CFRunLoopTimerSetNextFireDate(m_timer.get(), CFAbsoluteTimeGetCurrent() + s_decade); } +#elif PLATFORM(BLACKBERRY) + +IncrementalSweeper::IncrementalSweeper(Heap* heap) + : HeapTimer(heap->globalData()) + , m_currentBlockToSweepIndex(0) + , m_structuresCanBeSwept(false) +{ +} + +IncrementalSweeper* IncrementalSweeper::create(Heap* heap) +{ + return new IncrementalSweeper(heap); +} + +void IncrementalSweeper::scheduleTimer() +{ + m_timer.start(sweepTimeSlice * sweepTimeMultiplier); +} + +void IncrementalSweeper::cancelTimer() +{ + m_timer.stop(); +} + +#endif + +void IncrementalSweeper::doWork() +{ + doSweep(WTF::monotonicallyIncreasingTime()); +} + void IncrementalSweeper::doSweep(double sweepBeginTime) { while (m_currentBlockToSweepIndex < m_blocksToSweep.size()) { sweepNextBlock(); - CFTimeInterval elapsedTime = WTF::monotonicallyIncreasingTime() - sweepBeginTime; + double elapsedTime = WTF::monotonicallyIncreasingTime() - sweepBeginTime; if (elapsedTime < sweepTimeSlice) continue; diff --git a/Source/JavaScriptCore/heap/IncrementalSweeper.h b/Source/JavaScriptCore/heap/IncrementalSweeper.h index c8005b071..03c620f9c 100644 --- a/Source/JavaScriptCore/heap/IncrementalSweeper.h +++ b/Source/JavaScriptCore/heap/IncrementalSweeper.h @@ -60,8 +60,12 @@ public: void willFinishSweeping(); private: +#if USE(CF) || PLATFORM(BLACKBERRY) #if USE(CF) IncrementalSweeper(Heap*, CFRunLoopRef); +#else + IncrementalSweeper(Heap*); +#endif void doSweep(double startTime); void scheduleTimer(); diff --git a/Source/JavaScriptCore/heap/JITStubRoutineSet.cpp b/Source/JavaScriptCore/heap/JITStubRoutineSet.cpp index 054bf06dd..5e4ca36e0 100644 --- a/Source/JavaScriptCore/heap/JITStubRoutineSet.cpp +++ b/Source/JavaScriptCore/heap/JITStubRoutineSet.cpp @@ -29,7 +29,7 @@ #if ENABLE(JIT) #include "GCAwareJITStubRoutine.h" -#include "ScopeChain.h" + #include "SlotVisitor.h" namespace JSC { diff --git a/Source/JavaScriptCore/heap/MachineStackMarker.cpp b/Source/JavaScriptCore/heap/MachineStackMarker.cpp index 3c7ff9c3e..26453c4f3 100644 --- a/Source/JavaScriptCore/heap/MachineStackMarker.cpp +++ b/Source/JavaScriptCore/heap/MachineStackMarker.cpp @@ -107,6 +107,7 @@ static void pthreadSignalHandlerSuspendResume(int signo) #endif class MachineThreads::Thread { + WTF_MAKE_FAST_ALLOCATED; public: Thread(const PlatformThread& platThread, void* base) : platformThread(platThread) diff --git a/Source/JavaScriptCore/heap/MarkStack.cpp b/Source/JavaScriptCore/heap/MarkStack.cpp index 9d3062154..9a4a01f04 100644 --- a/Source/JavaScriptCore/heap/MarkStack.cpp +++ b/Source/JavaScriptCore/heap/MarkStack.cpp @@ -35,10 +35,9 @@ #include "JSArray.h" #include "JSCell.h" #include "JSObject.h" -#include "ScopeChain.h" + #include "SlotVisitorInlineMethods.h" #include "Structure.h" -#include "UString.h" #include "WriteBarrier.h" #include <wtf/Atomics.h> #include <wtf/DataLog.h> @@ -523,6 +522,8 @@ ALWAYS_INLINE void MarkStack::internalAppend(JSValue* slot) return; JSCell* cell = value.asCell(); + if (!cell) + return; if (m_shouldHashConst && cell->isString()) { JSString* string = jsCast<JSString*>(cell); diff --git a/Source/JavaScriptCore/heap/MarkStackInlineMethods.h b/Source/JavaScriptCore/heap/MarkStackInlineMethods.h index 8b420d637..031dfff39 100644 --- a/Source/JavaScriptCore/heap/MarkStackInlineMethods.h +++ b/Source/JavaScriptCore/heap/MarkStackInlineMethods.h @@ -35,8 +35,6 @@ ALWAYS_INLINE void MarkStack::append(JSValue* slot, size_t count) { for (size_t i = 0; i < count; ++i) { JSValue& value = slot[i]; - if (!value) - continue; internalAppend(value); } } @@ -46,8 +44,7 @@ inline void MarkStack::appendUnbarrieredPointer(T** slot) { ASSERT(slot); JSCell* cell = *slot; - if (cell) - internalAppend(cell); + internalAppend(cell); } ALWAYS_INLINE void MarkStack::append(JSValue* slot) @@ -70,8 +67,7 @@ ALWAYS_INLINE void MarkStack::append(JSCell** slot) ALWAYS_INLINE void MarkStack::internalAppend(JSValue value) { - ASSERT(value); - if (!value.isCell()) + if (!value || !value.isCell()) return; internalAppend(value.asCell()); } diff --git a/Source/JavaScriptCore/heap/MarkedBlock.cpp b/Source/JavaScriptCore/heap/MarkedBlock.cpp index 95ea2f414..b0f3b88d5 100644 --- a/Source/JavaScriptCore/heap/MarkedBlock.cpp +++ b/Source/JavaScriptCore/heap/MarkedBlock.cpp @@ -29,7 +29,7 @@ #include "IncrementalSweeper.h" #include "JSCell.h" #include "JSObject.h" -#include "ScopeChain.h" + namespace JSC { @@ -45,7 +45,7 @@ MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, Heap* heap, si , m_cellsNeedDestruction(cellsNeedDestruction) , m_onlyContainsStructures(onlyContainsStructures) , m_state(New) // All cells start out unmarked. - , m_weakSet(heap) + , m_weakSet(heap->globalData()) { ASSERT(heap); HEAP_LOG_BLOCK_STATE_TRANSITION(this); diff --git a/Source/JavaScriptCore/heap/MarkedBlock.h b/Source/JavaScriptCore/heap/MarkedBlock.h index ab2abd753..8c03d5b4f 100644 --- a/Source/JavaScriptCore/heap/MarkedBlock.h +++ b/Source/JavaScriptCore/heap/MarkedBlock.h @@ -121,6 +121,7 @@ namespace JSC { void lastChanceToFinalize(); Heap* heap() const; + JSGlobalData* globalData() const; WeakSet& weakSet(); enum SweepMode { SweepOnly, SweepToFreeList }; @@ -185,6 +186,7 @@ namespace JSC { #endif template <typename Functor> void forEachCell(Functor&); + template <typename Functor> void forEachDeadCell(Functor&); private: static const size_t atomAlignmentMask = atomSize - 1; // atomSize must be a power of two. @@ -262,6 +264,11 @@ namespace JSC { return m_weakSet.heap(); } + inline JSGlobalData* MarkedBlock::globalData() const + { + return m_weakSet.globalData(); + } + inline WeakSet& MarkedBlock::weakSet() { return m_weakSet; @@ -411,6 +418,17 @@ namespace JSC { } } + template <typename Functor> inline void MarkedBlock::forEachDeadCell(Functor& functor) + { + for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) { + JSCell* cell = reinterpret_cast_ptr<JSCell*>(&atoms()[i]); + if (isLive(cell)) + continue; + + functor(cell); + } + } + inline bool MarkedBlock::needsSweeping() { return m_state == Marked || m_state == Zapped; diff --git a/Source/JavaScriptCore/heap/MarkedSpace.cpp b/Source/JavaScriptCore/heap/MarkedSpace.cpp index cd6be001c..68b059c36 100644 --- a/Source/JavaScriptCore/heap/MarkedSpace.cpp +++ b/Source/JavaScriptCore/heap/MarkedSpace.cpp @@ -25,7 +25,7 @@ #include "JSGlobalObject.h" #include "JSLock.h" #include "JSObject.h" -#include "ScopeChain.h" + namespace JSC { diff --git a/Source/JavaScriptCore/heap/WeakBlock.cpp b/Source/JavaScriptCore/heap/WeakBlock.cpp index 05a44ea7e..13039e702 100644 --- a/Source/JavaScriptCore/heap/WeakBlock.cpp +++ b/Source/JavaScriptCore/heap/WeakBlock.cpp @@ -29,7 +29,7 @@ #include "Heap.h" #include "HeapRootVisitor.h" #include "JSObject.h" -#include "ScopeChain.h" + #include "Structure.h" namespace JSC { diff --git a/Source/JavaScriptCore/heap/WeakSet.cpp b/Source/JavaScriptCore/heap/WeakSet.cpp index 4a510b899..2804968f8 100644 --- a/Source/JavaScriptCore/heap/WeakSet.cpp +++ b/Source/JavaScriptCore/heap/WeakSet.cpp @@ -27,6 +27,7 @@ #include "WeakSet.h" #include "Heap.h" +#include "JSGlobalData.h" namespace JSC { @@ -73,7 +74,7 @@ WeakBlock::FreeCell* WeakSet::tryFindAllocator() WeakBlock::FreeCell* WeakSet::addAllocator() { WeakBlock* block = WeakBlock::create(); - m_heap->didAllocate(WeakBlock::blockSize); + heap()->didAllocate(WeakBlock::blockSize); m_blocks.append(block); WeakBlock::SweepResult sweepResult = block->takeSweepResult(); ASSERT(!sweepResult.isNull() && sweepResult.freeList); diff --git a/Source/JavaScriptCore/heap/WeakSet.h b/Source/JavaScriptCore/heap/WeakSet.h index 291d0aebd..06514eb69 100644 --- a/Source/JavaScriptCore/heap/WeakSet.h +++ b/Source/JavaScriptCore/heap/WeakSet.h @@ -38,11 +38,12 @@ public: static WeakImpl* allocate(JSValue, WeakHandleOwner* = 0, void* context = 0); static void deallocate(WeakImpl*); - WeakSet(Heap*); + WeakSet(JSGlobalData*); ~WeakSet(); void lastChanceToFinalize(); Heap* heap() const; + JSGlobalData* globalData() const; bool isEmpty() const; @@ -61,19 +62,19 @@ private: WeakBlock::FreeCell* m_allocator; WeakBlock* m_nextAllocator; DoublyLinkedList<WeakBlock> m_blocks; - Heap* m_heap; + JSGlobalData* m_globalData; }; -inline WeakSet::WeakSet(Heap* heap) +inline WeakSet::WeakSet(JSGlobalData* globalData) : m_allocator(0) , m_nextAllocator(0) - , m_heap(heap) + , m_globalData(globalData) { } -inline Heap* WeakSet::heap() const +inline JSGlobalData* WeakSet::globalData() const { - return m_heap; + return m_globalData; } inline bool WeakSet::isEmpty() const |