summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/heap
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/heap')
-rw-r--r--Source/JavaScriptCore/heap/Handle.h2
-rw-r--r--Source/JavaScriptCore/heap/Heap.cpp48
-rw-r--r--Source/JavaScriptCore/heap/Heap.h6
-rw-r--r--Source/JavaScriptCore/heap/HeapTimer.cpp6
-rw-r--r--Source/JavaScriptCore/heap/IncrementalSweeper.cpp48
-rw-r--r--Source/JavaScriptCore/heap/IncrementalSweeper.h4
-rw-r--r--Source/JavaScriptCore/heap/JITStubRoutineSet.cpp2
-rw-r--r--Source/JavaScriptCore/heap/MachineStackMarker.cpp1
-rw-r--r--Source/JavaScriptCore/heap/MarkStack.cpp5
-rw-r--r--Source/JavaScriptCore/heap/MarkStackInlineMethods.h8
-rw-r--r--Source/JavaScriptCore/heap/MarkedBlock.cpp4
-rw-r--r--Source/JavaScriptCore/heap/MarkedBlock.h18
-rw-r--r--Source/JavaScriptCore/heap/MarkedSpace.cpp2
-rw-r--r--Source/JavaScriptCore/heap/WeakBlock.cpp2
-rw-r--r--Source/JavaScriptCore/heap/WeakSet.cpp3
-rw-r--r--Source/JavaScriptCore/heap/WeakSet.h13
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