summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/heap
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-11-22 09:09:45 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2012-11-22 09:10:13 +0100
commit470286ecfe79d59df14944e5b5d34630fc739391 (patch)
tree43983212872e06cebefd2ae474418fa2908ca54c /Source/JavaScriptCore/heap
parent23037105e948c2065da5a937d3a2396b0ff45c1e (diff)
downloadqtwebkit-470286ecfe79d59df14944e5b5d34630fc739391.tar.gz
Imported WebKit commit e89504fa9195b2063b2530961d4b73dd08de3242 (http://svn.webkit.org/repository/webkit/trunk@135485)
Change-Id: I03774e5ac79721c13ffa30d152537a74d0b12e66 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'Source/JavaScriptCore/heap')
-rw-r--r--Source/JavaScriptCore/heap/BlockAllocator.cpp2
-rw-r--r--Source/JavaScriptCore/heap/BlockAllocator.h20
-rw-r--r--Source/JavaScriptCore/heap/ConservativeRoots.cpp4
-rw-r--r--Source/JavaScriptCore/heap/CopiedBlock.h2
-rw-r--r--Source/JavaScriptCore/heap/CopiedSpace.cpp2
-rw-r--r--Source/JavaScriptCore/heap/CopiedSpaceInlines.h (renamed from Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h)7
-rw-r--r--Source/JavaScriptCore/heap/CopyVisitor.cpp2
-rw-r--r--Source/JavaScriptCore/heap/CopyVisitorInlines.h (renamed from Source/JavaScriptCore/heap/CopyVisitorInlineMethods.h)7
-rw-r--r--Source/JavaScriptCore/heap/GCThread.cpp2
-rw-r--r--Source/JavaScriptCore/heap/GCThreadSharedData.cpp7
-rw-r--r--Source/JavaScriptCore/heap/GCThreadSharedData.h2
-rw-r--r--Source/JavaScriptCore/heap/HandleStack.cpp2
-rw-r--r--Source/JavaScriptCore/heap/Heap.cpp8
-rw-r--r--Source/JavaScriptCore/heap/Heap.h2
-rw-r--r--Source/JavaScriptCore/heap/HeapRootVisitor.h2
-rw-r--r--Source/JavaScriptCore/heap/HeapStatistics.cpp38
-rw-r--r--Source/JavaScriptCore/heap/HeapStatistics.h4
-rw-r--r--Source/JavaScriptCore/heap/JITStubRoutineSet.h3
-rw-r--r--Source/JavaScriptCore/heap/MarkStack.cpp154
-rw-r--r--Source/JavaScriptCore/heap/MarkStack.h59
-rw-r--r--Source/JavaScriptCore/heap/MarkStackInlines.h (renamed from Source/JavaScriptCore/heap/MarkStackInlineMethods.h)40
-rw-r--r--Source/JavaScriptCore/heap/MarkedBlock.h2
-rw-r--r--Source/JavaScriptCore/heap/SlotVisitor.cpp11
-rw-r--r--Source/JavaScriptCore/heap/SlotVisitor.h5
-rw-r--r--Source/JavaScriptCore/heap/SlotVisitorInlines.h (renamed from Source/JavaScriptCore/heap/SlotVisitorInlineMethods.h)17
-rw-r--r--Source/JavaScriptCore/heap/Weak.h5
26 files changed, 199 insertions, 210 deletions
diff --git a/Source/JavaScriptCore/heap/BlockAllocator.cpp b/Source/JavaScriptCore/heap/BlockAllocator.cpp
index daba93805..2d7b57f9a 100644
--- a/Source/JavaScriptCore/heap/BlockAllocator.cpp
+++ b/Source/JavaScriptCore/heap/BlockAllocator.cpp
@@ -36,7 +36,7 @@ namespace JSC {
BlockAllocator::BlockAllocator()
: m_copiedRegionSet(CopiedBlock::blockSize)
, m_markedRegionSet(MarkedBlock::blockSize)
- , m_weakRegionSet(WeakBlock::blockSize)
+ , m_weakAndMarkStackRegionSet(WeakBlock::blockSize)
, m_numberOfEmptyRegions(0)
, m_isCurrentlyAllocating(false)
, m_blockFreeingThreadShouldQuit(false)
diff --git a/Source/JavaScriptCore/heap/BlockAllocator.h b/Source/JavaScriptCore/heap/BlockAllocator.h
index f8ce39530..75c59b783 100644
--- a/Source/JavaScriptCore/heap/BlockAllocator.h
+++ b/Source/JavaScriptCore/heap/BlockAllocator.h
@@ -37,6 +37,7 @@ namespace JSC {
class BlockAllocator;
class CopiedBlock;
+class MarkStackSegment;
class MarkedBlock;
class Region;
class WeakBlock;
@@ -185,7 +186,8 @@ private:
RegionSet m_copiedRegionSet;
RegionSet m_markedRegionSet;
- RegionSet m_weakRegionSet;
+ // WeakBlocks and MarkStackSegments use the same RegionSet since they're the same size.
+ RegionSet m_weakAndMarkStackRegionSet;
DoublyLinkedList<Region> m_emptyRegions;
size_t m_numberOfEmptyRegions;
@@ -315,7 +317,13 @@ inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<MarkedBlock>()
template <>
inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<WeakBlock>()
{
- return m_weakRegionSet;
+ return m_weakAndMarkStackRegionSet;
+}
+
+template <>
+inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<MarkStackSegment>()
+{
+ return m_weakAndMarkStackRegionSet;
}
template <>
@@ -333,7 +341,13 @@ inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<MarkedB
template <>
inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<WeakBlock> >()
{
- return m_weakRegionSet;
+ return m_weakAndMarkStackRegionSet;
+}
+
+template <>
+inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<MarkStackSegment> >()
+{
+ return m_weakAndMarkStackRegionSet;
}
template <typename T>
diff --git a/Source/JavaScriptCore/heap/ConservativeRoots.cpp b/Source/JavaScriptCore/heap/ConservativeRoots.cpp
index 7fe22dfff..752ce2775 100644
--- a/Source/JavaScriptCore/heap/ConservativeRoots.cpp
+++ b/Source/JavaScriptCore/heap/ConservativeRoots.cpp
@@ -26,9 +26,9 @@
#include "config.h"
#include "ConservativeRoots.h"
-#include "CopiedSpace.h"
-#include "CopiedSpaceInlineMethods.h"
#include "CodeBlock.h"
+#include "CopiedSpace.h"
+#include "CopiedSpaceInlines.h"
#include "DFGCodeBlocks.h"
#include "JSCell.h"
#include "JSObject.h"
diff --git a/Source/JavaScriptCore/heap/CopiedBlock.h b/Source/JavaScriptCore/heap/CopiedBlock.h
index af36f55df..83fdb08da 100644
--- a/Source/JavaScriptCore/heap/CopiedBlock.h
+++ b/Source/JavaScriptCore/heap/CopiedBlock.h
@@ -29,7 +29,7 @@
#include "BlockAllocator.h"
#include "HeapBlock.h"
#include "JSValue.h"
-#include "JSValueInlineMethods.h"
+#include "JSValueInlines.h"
#include "Options.h"
#include <wtf/Atomics.h>
diff --git a/Source/JavaScriptCore/heap/CopiedSpace.cpp b/Source/JavaScriptCore/heap/CopiedSpace.cpp
index c228f9460..e4141c1d7 100644
--- a/Source/JavaScriptCore/heap/CopiedSpace.cpp
+++ b/Source/JavaScriptCore/heap/CopiedSpace.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "CopiedSpace.h"
-#include "CopiedSpaceInlineMethods.h"
+#include "CopiedSpaceInlines.h"
#include "GCActivityCallback.h"
#include "Options.h"
diff --git a/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h b/Source/JavaScriptCore/heap/CopiedSpaceInlines.h
index c244015e7..9d222f549 100644
--- a/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h
+++ b/Source/JavaScriptCore/heap/CopiedSpaceInlines.h
@@ -23,8 +23,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef CopiedSpaceInlineMethods_h
-#define CopiedSpaceInlineMethods_h
+#ifndef CopiedSpaceInlines_h
+#define CopiedSpaceInlines_h
#include "CopiedBlock.h"
#include "CopiedSpace.h"
@@ -182,4 +182,5 @@ inline CopiedBlock* CopiedSpace::blockFor(void* ptr)
} // namespace JSC
-#endif
+#endif // CopiedSpaceInlines_h
+
diff --git a/Source/JavaScriptCore/heap/CopyVisitor.cpp b/Source/JavaScriptCore/heap/CopyVisitor.cpp
index ae826f0d2..22ab57882 100644
--- a/Source/JavaScriptCore/heap/CopyVisitor.cpp
+++ b/Source/JavaScriptCore/heap/CopyVisitor.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "CopyVisitor.h"
-#include "CopyVisitorInlineMethods.h"
+#include "CopyVisitorInlines.h"
#include "GCThreadSharedData.h"
#include "JSCell.h"
#include "JSObject.h"
diff --git a/Source/JavaScriptCore/heap/CopyVisitorInlineMethods.h b/Source/JavaScriptCore/heap/CopyVisitorInlines.h
index eb7bd2e82..bd7879429 100644
--- a/Source/JavaScriptCore/heap/CopyVisitorInlineMethods.h
+++ b/Source/JavaScriptCore/heap/CopyVisitorInlines.h
@@ -23,8 +23,8 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef CopyVisitorInlineMethods_h
-#define CopyVisitorInlineMethods_h
+#ifndef CopyVisitorInlines_h
+#define CopyVisitorInlines_h
#include "ClassInfo.h"
#include "CopyVisitor.h"
@@ -116,4 +116,5 @@ inline void CopyVisitor::didCopy(void* ptr, size_t bytes)
} // namespace JSC
-#endif
+#endif // CopyVisitorInlines_h
+
diff --git a/Source/JavaScriptCore/heap/GCThread.cpp b/Source/JavaScriptCore/heap/GCThread.cpp
index ce3bbedc9..7caa7d588 100644
--- a/Source/JavaScriptCore/heap/GCThread.cpp
+++ b/Source/JavaScriptCore/heap/GCThread.cpp
@@ -27,7 +27,7 @@
#include "GCThread.h"
#include "CopyVisitor.h"
-#include "CopyVisitorInlineMethods.h"
+#include "CopyVisitorInlines.h"
#include "GCThreadSharedData.h"
#include "SlotVisitor.h"
#include <wtf/MainThread.h>
diff --git a/Source/JavaScriptCore/heap/GCThreadSharedData.cpp b/Source/JavaScriptCore/heap/GCThreadSharedData.cpp
index 446b41c2f..f513fafab 100644
--- a/Source/JavaScriptCore/heap/GCThreadSharedData.cpp
+++ b/Source/JavaScriptCore/heap/GCThreadSharedData.cpp
@@ -27,12 +27,12 @@
#include "GCThreadSharedData.h"
#include "CopyVisitor.h"
-#include "CopyVisitorInlineMethods.h"
+#include "CopyVisitorInlines.h"
#include "GCThread.h"
#include "JSGlobalData.h"
#include "MarkStack.h"
#include "SlotVisitor.h"
-#include "SlotVisitorInlineMethods.h"
+#include "SlotVisitorInlines.h"
namespace JSC {
@@ -56,7 +56,7 @@ GCThreadSharedData::GCThreadSharedData(JSGlobalData* globalData)
: m_globalData(globalData)
, m_copiedSpace(&globalData->heap.m_storageSpace)
, m_shouldHashConst(false)
- , m_sharedMarkStack(m_segmentAllocator)
+ , m_sharedMarkStack(globalData->heap.blockAllocator())
, m_numberOfActiveParallelMarkers(0)
, m_parallelMarkersShouldExit(false)
, m_blocksToCopy(globalData->heap.m_blockSnapshot)
@@ -110,7 +110,6 @@ void GCThreadSharedData::reset()
ASSERT(m_sharedMarkStack.isEmpty());
#if ENABLE(PARALLEL_GC)
- m_segmentAllocator.shrinkReserve();
m_opaqueRoots.clear();
#else
ASSERT(m_opaqueRoots.isEmpty());
diff --git a/Source/JavaScriptCore/heap/GCThreadSharedData.h b/Source/JavaScriptCore/heap/GCThreadSharedData.h
index f341afc04..b80cc5af2 100644
--- a/Source/JavaScriptCore/heap/GCThreadSharedData.h
+++ b/Source/JavaScriptCore/heap/GCThreadSharedData.h
@@ -80,8 +80,6 @@ private:
JSGlobalData* m_globalData;
CopiedSpace* m_copiedSpace;
- MarkStackSegmentAllocator m_segmentAllocator;
-
bool m_shouldHashConst;
Vector<GCThread*> m_gcThreads;
diff --git a/Source/JavaScriptCore/heap/HandleStack.cpp b/Source/JavaScriptCore/heap/HandleStack.cpp
index 42eb326a5..a5653c748 100644
--- a/Source/JavaScriptCore/heap/HandleStack.cpp
+++ b/Source/JavaScriptCore/heap/HandleStack.cpp
@@ -27,8 +27,8 @@
#include "HandleStack.h"
#include "HeapRootVisitor.h"
-#include "JSValueInlineMethods.h"
#include "JSObject.h"
+#include "JSValueInlines.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/heap/Heap.cpp b/Source/JavaScriptCore/heap/Heap.cpp
index c455fc2b1..9ff318b08 100644
--- a/Source/JavaScriptCore/heap/Heap.cpp
+++ b/Source/JavaScriptCore/heap/Heap.cpp
@@ -24,8 +24,8 @@
#include "CodeBlock.h"
#include "ConservativeRoots.h"
#include "CopiedSpace.h"
-#include "CopiedSpaceInlineMethods.h"
-#include "CopyVisitorInlineMethods.h"
+#include "CopiedSpaceInlines.h"
+#include "CopyVisitorInlines.h"
#include "GCActivityCallback.h"
#include "HeapRootVisitor.h"
#include "HeapStatistics.h"
@@ -76,7 +76,7 @@ struct GCTimer {
}
~GCTimer()
{
- dataLog("%s: %.2lfms (avg. %.2lf, min. %.2lf, max. %.2lf)\n", m_name, m_time * 1000, m_time * 1000 / m_count, m_min*1000, m_max*1000);
+ dataLogF("%s: %.2lfms (avg. %.2lf, min. %.2lf, max. %.2lf)\n", m_name, m_time * 1000, m_time * 1000 / m_count, m_min*1000, m_max*1000);
}
double m_time;
double m_min;
@@ -126,7 +126,7 @@ struct GCCounter {
}
~GCCounter()
{
- dataLog("%s: %zu values (avg. %zu, min. %zu, max. %zu)\n", m_name, m_total, m_total / m_count, m_min, m_max);
+ dataLogF("%s: %zu values (avg. %zu, min. %zu, max. %zu)\n", m_name, m_total, m_total / m_count, m_min, m_max);
}
const char* m_name;
size_t m_count;
diff --git a/Source/JavaScriptCore/heap/Heap.h b/Source/JavaScriptCore/heap/Heap.h
index d0d03959b..90c9f2ab1 100644
--- a/Source/JavaScriptCore/heap/Heap.h
+++ b/Source/JavaScriptCore/heap/Heap.h
@@ -174,6 +174,8 @@ namespace JSC {
bool isPagedOut(double deadline);
void didStartVMShutdown();
+
+ const JITStubRoutineSet& jitStubRoutines() { return m_jitStubRoutines; }
private:
friend class CodeBlock;
diff --git a/Source/JavaScriptCore/heap/HeapRootVisitor.h b/Source/JavaScriptCore/heap/HeapRootVisitor.h
index 9849d7c39..5b11a5ead 100644
--- a/Source/JavaScriptCore/heap/HeapRootVisitor.h
+++ b/Source/JavaScriptCore/heap/HeapRootVisitor.h
@@ -27,7 +27,7 @@
#define HeapRootVisitor_h
#include "SlotVisitor.h"
-#include "SlotVisitorInlineMethods.h"
+#include "SlotVisitorInlines.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/heap/HeapStatistics.cpp b/Source/JavaScriptCore/heap/HeapStatistics.cpp
index 8340bfa37..2b98fe711 100644
--- a/Source/JavaScriptCore/heap/HeapStatistics.cpp
+++ b/Source/JavaScriptCore/heap/HeapStatistics.cpp
@@ -41,8 +41,8 @@ namespace JSC {
double HeapStatistics::s_startTime = 0.0;
double HeapStatistics::s_endTime = 0.0;
-Deque<double>* HeapStatistics::s_pauseTimeStarts = 0;
-Deque<double>* HeapStatistics::s_pauseTimeEnds = 0;
+Vector<double>* HeapStatistics::s_pauseTimeStarts = 0;
+Vector<double>* HeapStatistics::s_pauseTimeEnds = 0;
#if OS(UNIX)
@@ -50,8 +50,8 @@ void HeapStatistics::initialize()
{
ASSERT(Options::recordGCPauseTimes());
s_startTime = WTF::monotonicallyIncreasingTime();
- s_pauseTimeStarts = new Deque<double>();
- s_pauseTimeEnds = new Deque<double>();
+ s_pauseTimeStarts = new Vector<double>();
+ s_pauseTimeEnds = new Vector<double>();
}
void HeapStatistics::recordGCPauseTime(double start, double end)
@@ -75,28 +75,28 @@ void HeapStatistics::logStatistics()
#error "The HeapStatistics module is not supported on this platform."
#endif
if (!vmName || !suiteName || !benchmarkName)
- dataLog("HeapStatistics: {\"max_rss\": %ld", usage.ru_maxrss);
+ dataLogF("HeapStatistics: {\"max_rss\": %ld", usage.ru_maxrss);
else
- dataLog("HeapStatistics: {\"max_rss\": %ld, \"vm_name\": \"%s\", \"suite_name\": \"%s\", \"benchmark_name\": \"%s\"",
+ dataLogF("HeapStatistics: {\"max_rss\": %ld, \"vm_name\": \"%s\", \"suite_name\": \"%s\", \"benchmark_name\": \"%s\"",
usage.ru_maxrss, vmName, suiteName, benchmarkName);
if (Options::recordGCPauseTimes()) {
- dataLog(", \"pause_times\": [");
- Deque<double>::iterator startIt = s_pauseTimeStarts->begin();
- Deque<double>::iterator endIt = s_pauseTimeEnds->begin();
+ dataLogF(", \"pause_times\": [");
+ Vector<double>::iterator startIt = s_pauseTimeStarts->begin();
+ Vector<double>::iterator endIt = s_pauseTimeEnds->begin();
if (startIt != s_pauseTimeStarts->end() && endIt != s_pauseTimeEnds->end()) {
- dataLog("[%f, %f]", *startIt, *endIt);
+ dataLogF("[%f, %f]", *startIt, *endIt);
++startIt;
++endIt;
}
while (startIt != s_pauseTimeStarts->end() && endIt != s_pauseTimeEnds->end()) {
- dataLog(", [%f, %f]", *startIt, *endIt);
+ dataLogF(", [%f, %f]", *startIt, *endIt);
++startIt;
++endIt;
}
- dataLog("], \"start_time\": %f, \"end_time\": %f", s_startTime, s_endTime);
+ dataLogF("], \"start_time\": %f, \"end_time\": %f", s_startTime, s_endTime);
}
- dataLog("}\n");
+ dataLogF("}\n");
}
void HeapStatistics::exitWithFailure()
@@ -228,20 +228,20 @@ inline size_t StorageStatistics::storageCapacity()
void HeapStatistics::showObjectStatistics(Heap* heap)
{
- dataLog("\n=== Heap Statistics: ===\n");
- dataLog("size: %ldkB\n", static_cast<long>(heap->m_sizeAfterLastCollect / KB));
- dataLog("capacity: %ldkB\n", static_cast<long>(heap->capacity() / KB));
- dataLog("pause time: %lfms\n\n", heap->m_lastGCLength);
+ dataLogF("\n=== Heap Statistics: ===\n");
+ dataLogF("size: %ldkB\n", static_cast<long>(heap->m_sizeAfterLastCollect / KB));
+ dataLogF("capacity: %ldkB\n", static_cast<long>(heap->capacity() / KB));
+ dataLogF("pause time: %lfms\n\n", heap->m_lastGCLength);
StorageStatistics storageStatistics;
heap->m_objectSpace.forEachLiveCell(storageStatistics);
- dataLog("wasted .property storage: %ldkB (%ld%%)\n",
+ dataLogF("wasted .property storage: %ldkB (%ld%%)\n",
static_cast<long>(
(storageStatistics.storageCapacity() - storageStatistics.storageSize()) / KB),
static_cast<long>(
(storageStatistics.storageCapacity() - storageStatistics.storageSize()) * 100
/ storageStatistics.storageCapacity()));
- dataLog("objects with out-of-line .property storage: %ld (%ld%%)\n",
+ dataLogF("objects with out-of-line .property storage: %ld (%ld%%)\n",
static_cast<long>(
storageStatistics.objectWithOutOfLineStorageCount()),
static_cast<long>(
diff --git a/Source/JavaScriptCore/heap/HeapStatistics.h b/Source/JavaScriptCore/heap/HeapStatistics.h
index 0800f0c16..ce7a40a79 100644
--- a/Source/JavaScriptCore/heap/HeapStatistics.h
+++ b/Source/JavaScriptCore/heap/HeapStatistics.h
@@ -49,8 +49,8 @@ public:
private:
static void logStatistics();
- static Deque<double>* s_pauseTimeStarts;
- static Deque<double>* s_pauseTimeEnds;
+ static Vector<double>* s_pauseTimeStarts;
+ static Vector<double>* s_pauseTimeEnds;
static double s_startTime;
static double s_endTime;
};
diff --git a/Source/JavaScriptCore/heap/JITStubRoutineSet.h b/Source/JavaScriptCore/heap/JITStubRoutineSet.h
index cb76ac8bd..2c2e9fa86 100644
--- a/Source/JavaScriptCore/heap/JITStubRoutineSet.h
+++ b/Source/JavaScriptCore/heap/JITStubRoutineSet.h
@@ -65,6 +65,9 @@ public:
void traceMarkedStubRoutines(SlotVisitor&);
+ unsigned size() const { return m_listOfRoutines.size(); }
+ GCAwareJITStubRoutine* at(unsigned i) const { return m_listOfRoutines[i]; }
+
private:
void markSlow(uintptr_t address);
diff --git a/Source/JavaScriptCore/heap/MarkStack.cpp b/Source/JavaScriptCore/heap/MarkStack.cpp
index 582439fd2..755a0ad50 100644
--- a/Source/JavaScriptCore/heap/MarkStack.cpp
+++ b/Source/JavaScriptCore/heap/MarkStack.cpp
@@ -25,18 +25,18 @@
#include "config.h"
#include "MarkStack.h"
-#include "MarkStackInlineMethods.h"
+#include "MarkStackInlines.h"
-#include "CopiedSpace.h"
-#include "CopiedSpaceInlineMethods.h"
#include "ConservativeRoots.h"
+#include "CopiedSpace.h"
+#include "CopiedSpaceInlines.h"
#include "Heap.h"
#include "Options.h"
#include "JSArray.h"
#include "JSCell.h"
#include "JSObject.h"
-#include "SlotVisitorInlineMethods.h"
+#include "SlotVisitorInlines.h"
#include "Structure.h"
#include "WriteBarrier.h"
#include <wtf/Atomics.h>
@@ -45,84 +45,35 @@
namespace JSC {
-MarkStackSegmentAllocator::MarkStackSegmentAllocator()
- : m_nextFreeSegment(0)
-{
- m_lock.Init();
-}
-
-MarkStackSegmentAllocator::~MarkStackSegmentAllocator()
-{
- shrinkReserve();
-}
-
-MarkStackSegment* MarkStackSegmentAllocator::allocate()
-{
- {
- SpinLockHolder locker(&m_lock);
- if (m_nextFreeSegment) {
- MarkStackSegment* result = m_nextFreeSegment;
- m_nextFreeSegment = result->m_previous;
- return result;
- }
- }
-
- return static_cast<MarkStackSegment*>(OSAllocator::reserveAndCommit(Options::gcMarkStackSegmentSize()));
-}
-
-void MarkStackSegmentAllocator::release(MarkStackSegment* segment)
-{
- SpinLockHolder locker(&m_lock);
- segment->m_previous = m_nextFreeSegment;
- m_nextFreeSegment = segment;
-}
-
-void MarkStackSegmentAllocator::shrinkReserve()
-{
- MarkStackSegment* segments;
- {
- SpinLockHolder locker(&m_lock);
- segments = m_nextFreeSegment;
- m_nextFreeSegment = 0;
- }
- while (segments) {
- MarkStackSegment* toFree = segments;
- segments = segments->m_previous;
- OSAllocator::decommitAndRelease(toFree, Options::gcMarkStackSegmentSize());
- }
-}
-
-MarkStackArray::MarkStackArray(MarkStackSegmentAllocator& allocator)
- : m_allocator(allocator)
+MarkStackArray::MarkStackArray(BlockAllocator& blockAllocator)
+ : m_blockAllocator(blockAllocator)
, m_segmentCapacity(MarkStackSegment::capacityFromSize(Options::gcMarkStackSegmentSize()))
, m_top(0)
- , m_numberOfPreviousSegments(0)
+ , m_numberOfSegments(0)
{
- m_topSegment = m_allocator.allocate();
-#if !ASSERT_DISABLED
- m_topSegment->m_top = 0;
-#endif
- m_topSegment->m_previous = 0;
+ ASSERT(MarkStackSegment::blockSize == WeakBlock::blockSize);
+ m_segments.push(MarkStackSegment::create(m_blockAllocator.allocate<MarkStackSegment>()));
+ m_numberOfSegments++;
}
MarkStackArray::~MarkStackArray()
{
- ASSERT(!m_topSegment->m_previous);
- m_allocator.release(m_topSegment);
+ ASSERT(m_numberOfSegments == 1 && m_segments.size() == 1);
+ m_blockAllocator.deallocate(MarkStackSegment::destroy(m_segments.removeHead()));
}
void MarkStackArray::expand()
{
- ASSERT(m_topSegment->m_top == m_segmentCapacity);
+ ASSERT(m_segments.head()->m_top == m_segmentCapacity);
- m_numberOfPreviousSegments++;
+ MarkStackSegment* nextSegment = MarkStackSegment::create(m_blockAllocator.allocate<MarkStackSegment>());
+ m_numberOfSegments++;
- MarkStackSegment* nextSegment = m_allocator.allocate();
#if !ASSERT_DISABLED
nextSegment->m_top = 0;
#endif
- nextSegment->m_previous = m_topSegment;
- m_topSegment = nextSegment;
+
+ m_segments.push(nextSegment);
setTopForEmptySegment();
validatePrevious();
}
@@ -132,14 +83,9 @@ bool MarkStackArray::refill()
validatePrevious();
if (top())
return true;
- MarkStackSegment* toFree = m_topSegment;
- MarkStackSegment* previous = m_topSegment->m_previous;
- if (!previous)
- return false;
- ASSERT(m_numberOfPreviousSegments);
- m_numberOfPreviousSegments--;
- m_topSegment = previous;
- m_allocator.release(toFree);
+ m_blockAllocator.deallocate(MarkStackSegment::destroy(m_segments.removeHead()));
+ ASSERT(m_numberOfSegments > 1);
+ m_numberOfSegments--;
setTopForFullSegment();
validatePrevious();
return true;
@@ -153,7 +99,7 @@ void MarkStackArray::donateSomeCellsTo(MarkStackArray& other)
ASSERT(m_segmentCapacity == other.m_segmentCapacity);
- size_t segmentsToDonate = (m_numberOfPreviousSegments + 2 - 1) / 2; // Round up to donate 1 / 1 previous segments.
+ size_t segmentsToDonate = m_numberOfSegments / 2; // If we only have one segment (our head) we don't donate any segments.
if (!segmentsToDonate) {
size_t cellsToDonate = m_top / 2; // Round down to donate 0 / 1 cells.
@@ -167,21 +113,23 @@ void MarkStackArray::donateSomeCellsTo(MarkStackArray& other)
validatePrevious();
other.validatePrevious();
- MarkStackSegment* previous = m_topSegment->m_previous;
+ // Remove our head and the head of the other list before we start moving segments around.
+ // We'll add them back on once we're done donating.
+ MarkStackSegment* myHead = m_segments.removeHead();
+ MarkStackSegment* otherHead = other.m_segments.removeHead();
+
while (segmentsToDonate--) {
- ASSERT(previous);
- ASSERT(m_numberOfPreviousSegments);
-
- MarkStackSegment* current = previous;
- previous = current->m_previous;
-
- current->m_previous = other.m_topSegment->m_previous;
- other.m_topSegment->m_previous = current;
-
- m_numberOfPreviousSegments--;
- other.m_numberOfPreviousSegments++;
+ MarkStackSegment* current = m_segments.removeHead();
+ ASSERT(current);
+ ASSERT(m_numberOfSegments > 1);
+ other.m_segments.push(current);
+ m_numberOfSegments--;
+ other.m_numberOfSegments++;
}
- m_topSegment->m_previous = previous;
+
+ // Put the original heads back in their places.
+ m_segments.push(myHead);
+ other.m_segments.push(otherHead);
validatePrevious();
other.validatePrevious();
@@ -198,21 +146,21 @@ void MarkStackArray::stealSomeCellsFrom(MarkStackArray& other, size_t idleThread
other.validatePrevious();
// If other has an entire segment, steal it and return.
- if (other.m_topSegment->m_previous) {
- ASSERT(other.m_topSegment->m_previous->m_top == m_segmentCapacity);
-
- // First remove a segment from other.
- MarkStackSegment* current = other.m_topSegment->m_previous;
- other.m_topSegment->m_previous = current->m_previous;
- other.m_numberOfPreviousSegments--;
-
- ASSERT(!!other.m_numberOfPreviousSegments == !!other.m_topSegment->m_previous);
-
- // Now add it to this.
- current->m_previous = m_topSegment->m_previous;
- m_topSegment->m_previous = current;
- m_numberOfPreviousSegments++;
-
+ if (other.m_numberOfSegments > 1) {
+ // Move the heads of the lists aside. We'll push them back on after.
+ MarkStackSegment* otherHead = other.m_segments.removeHead();
+ MarkStackSegment* myHead = m_segments.removeHead();
+
+ ASSERT(other.m_segments.head()->m_top == m_segmentCapacity);
+
+ m_segments.push(other.m_segments.removeHead());
+
+ m_numberOfSegments++;
+ other.m_numberOfSegments--;
+
+ m_segments.push(myHead);
+ other.m_segments.push(otherHead);
+
validatePrevious();
other.validatePrevious();
return;
diff --git a/Source/JavaScriptCore/heap/MarkStack.h b/Source/JavaScriptCore/heap/MarkStack.h
index 0245e4be5..2a7f04450 100644
--- a/Source/JavaScriptCore/heap/MarkStack.h
+++ b/Source/JavaScriptCore/heap/MarkStack.h
@@ -27,19 +27,19 @@
#define MarkStack_h
#if ENABLE(OBJECT_MARK_LOGGING)
-#define MARK_LOG_MESSAGE0(message) dataLog(message)
-#define MARK_LOG_MESSAGE1(message, arg1) dataLog(message, arg1)
-#define MARK_LOG_MESSAGE2(message, arg1, arg2) dataLog(message, arg1, arg2)
+#define MARK_LOG_MESSAGE0(message) dataLogF(message)
+#define MARK_LOG_MESSAGE1(message, arg1) dataLogF(message, arg1)
+#define MARK_LOG_MESSAGE2(message, arg1, arg2) dataLogF(message, arg1, arg2)
#define MARK_LOG_ROOT(visitor, rootName) \
- dataLog("\n%s: ", rootName); \
+ dataLogF("\n%s: ", rootName); \
(visitor).resetChildCount()
#define MARK_LOG_PARENT(visitor, parent) \
- dataLog("\n%p (%s): ", parent, parent->className() ? parent->className() : "unknown"); \
+ dataLogF("\n%p (%s): ", parent, parent->className() ? parent->className() : "unknown"); \
(visitor).resetChildCount()
#define MARK_LOG_CHILD(visitor, child) \
if ((visitor).childCount()) \
- dataLogString(", "); \
- dataLog("%p", child); \
+ dataLogFString(", "); \
+ dataLogF("%p", child); \
(visitor).incrementChildCount()
#else
#define MARK_LOG_MESSAGE0(message) do { } while (false)
@@ -50,19 +50,27 @@
#define MARK_LOG_CHILD(visitor, child) do { } while (false)
#endif
+#include "HeapBlock.h"
#include <wtf/StdLibExtras.h>
-#include <wtf/TCSpinLock.h>
namespace JSC {
+class BlockAllocator;
+class DeadBlock;
class JSCell;
-struct MarkStackSegment {
- MarkStackSegment* m_previous;
+class MarkStackSegment : public HeapBlock<MarkStackSegment> {
+public:
+ MarkStackSegment(Region* region)
+ : HeapBlock<MarkStackSegment>(region)
#if !ASSERT_DISABLED
- size_t m_top;
+ , m_top(0)
#endif
-
+ {
+ }
+
+ static MarkStackSegment* create(DeadBlock*);
+
const JSCell** data()
{
return bitwise_cast<const JSCell**>(this + 1);
@@ -77,26 +85,17 @@ struct MarkStackSegment {
{
return sizeof(MarkStackSegment) + capacity * sizeof(const JSCell*);
}
-};
-class MarkStackSegmentAllocator {
-public:
- MarkStackSegmentAllocator();
- ~MarkStackSegmentAllocator();
-
- MarkStackSegment* allocate();
- void release(MarkStackSegment*);
-
- void shrinkReserve();
-
-private:
- SpinLock m_lock;
- MarkStackSegment* m_nextFreeSegment;
+ static const size_t blockSize = 4 * KB;
+
+#if !ASSERT_DISABLED
+ size_t m_top;
+#endif
};
class MarkStackArray {
public:
- MarkStackArray(MarkStackSegmentAllocator&);
+ MarkStackArray(BlockAllocator&);
~MarkStackArray();
void append(const JSCell*);
@@ -122,12 +121,12 @@ private:
void validatePrevious();
- MarkStackSegment* m_topSegment;
- MarkStackSegmentAllocator& m_allocator;
+ DoublyLinkedList<MarkStackSegment> m_segments;
+ BlockAllocator& m_blockAllocator;
size_t m_segmentCapacity;
size_t m_top;
- size_t m_numberOfPreviousSegments;
+ size_t m_numberOfSegments;
};
diff --git a/Source/JavaScriptCore/heap/MarkStackInlineMethods.h b/Source/JavaScriptCore/heap/MarkStackInlines.h
index d3276d7fa..1595e843e 100644
--- a/Source/JavaScriptCore/heap/MarkStackInlineMethods.h
+++ b/Source/JavaScriptCore/heap/MarkStackInlines.h
@@ -23,43 +23,48 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef MarkStackInlineMethods_h
-#define MarkStackInlineMethods_h
+#ifndef MarkStackInlines_h
+#define MarkStackInlines_h
#include "GCThreadSharedData.h"
#include "MarkStack.h"
namespace JSC {
+inline MarkStackSegment* MarkStackSegment::create(DeadBlock* block)
+{
+ return new (NotNull, block) MarkStackSegment(block->region());
+}
+
inline size_t MarkStackArray::postIncTop()
{
size_t result = m_top++;
- ASSERT(result == m_topSegment->m_top++);
+ ASSERT(result == m_segments.head()->m_top++);
return result;
}
-
+
inline size_t MarkStackArray::preDecTop()
{
size_t result = --m_top;
- ASSERT(result == --m_topSegment->m_top);
+ ASSERT(result == --m_segments.head()->m_top);
return result;
}
-
+
inline void MarkStackArray::setTopForFullSegment()
{
- ASSERT(m_topSegment->m_top == m_segmentCapacity);
+ ASSERT(m_segments.head()->m_top == m_segmentCapacity);
m_top = m_segmentCapacity;
}
inline void MarkStackArray::setTopForEmptySegment()
{
- ASSERT(!m_topSegment->m_top);
+ ASSERT(!m_segments.head()->m_top);
m_top = 0;
}
inline size_t MarkStackArray::top()
{
- ASSERT(m_top == m_topSegment->m_top);
+ ASSERT(m_top == m_segments.head()->m_top);
return m_top;
}
@@ -69,9 +74,9 @@ inline void MarkStackArray::validatePrevious() { }
inline void MarkStackArray::validatePrevious()
{
unsigned count = 0;
- for (MarkStackSegment* current = m_topSegment->m_previous; current; current = current->m_previous)
+ for (MarkStackSegment* current = m_segments.head(); current; current = current->next())
count++;
- ASSERT(count == m_numberOfPreviousSegments);
+ ASSERT(m_segments.size() == m_numberOfSegments);
}
#endif
@@ -79,7 +84,7 @@ inline void MarkStackArray::append(const JSCell* cell)
{
if (m_top == m_segmentCapacity)
expand();
- m_topSegment->data()[postIncTop()] = cell;
+ m_segments.head()->data()[postIncTop()] = cell;
}
inline bool MarkStackArray::canRemoveLast()
@@ -89,15 +94,15 @@ inline bool MarkStackArray::canRemoveLast()
inline const JSCell* MarkStackArray::removeLast()
{
- return m_topSegment->data()[preDecTop()];
+ return m_segments.head()->data()[preDecTop()];
}
inline bool MarkStackArray::isEmpty()
{
if (m_top)
return false;
- if (m_topSegment->m_previous) {
- ASSERT(m_topSegment->m_previous->m_top == m_segmentCapacity);
+ if (m_segments.head()->next()) {
+ ASSERT(m_segments.head()->next()->m_top == m_segmentCapacity);
return false;
}
return true;
@@ -105,9 +110,10 @@ inline bool MarkStackArray::isEmpty()
inline size_t MarkStackArray::size()
{
- return m_top + m_segmentCapacity * m_numberOfPreviousSegments;
+ return m_top + m_segmentCapacity * (m_numberOfSegments - 1);
}
} // namespace JSC
-#endif
+#endif // MarkStackInlines_h
+
diff --git a/Source/JavaScriptCore/heap/MarkedBlock.h b/Source/JavaScriptCore/heap/MarkedBlock.h
index f2f2a720d..9080aaef4 100644
--- a/Source/JavaScriptCore/heap/MarkedBlock.h
+++ b/Source/JavaScriptCore/heap/MarkedBlock.h
@@ -40,7 +40,7 @@
#if HEAP_LOG_BLOCK_STATE_TRANSITIONS
#define HEAP_LOG_BLOCK_STATE_TRANSITION(block) do { \
- dataLog( \
+ dataLogF( \
"%s:%d %s: block %s = %p, %d\n", \
__FILE__, __LINE__, __FUNCTION__, \
#block, (block), (block)->m_state); \
diff --git a/Source/JavaScriptCore/heap/SlotVisitor.cpp b/Source/JavaScriptCore/heap/SlotVisitor.cpp
index 3919705d0..3ff4b48fa 100644
--- a/Source/JavaScriptCore/heap/SlotVisitor.cpp
+++ b/Source/JavaScriptCore/heap/SlotVisitor.cpp
@@ -1,9 +1,10 @@
#include "config.h"
#include "SlotVisitor.h"
+#include "SlotVisitorInlines.h"
#include "ConservativeRoots.h"
#include "CopiedSpace.h"
-#include "CopiedSpaceInlineMethods.h"
+#include "CopiedSpaceInlines.h"
#include "GCThread.h"
#include "JSArray.h"
#include "JSDestructibleObject.h"
@@ -15,7 +16,7 @@
namespace JSC {
SlotVisitor::SlotVisitor(GCThreadSharedData& shared)
- : m_stack(shared.m_segmentAllocator)
+ : m_stack(shared.m_globalData->heap.blockAllocator())
, m_visitCount(0)
, m_isInParallelMode(false)
, m_shared(shared)
@@ -335,12 +336,12 @@ void SlotVisitor::finalizeUnconditionalFinalizers()
void SlotVisitor::validate(JSCell* cell)
{
if (!cell) {
- dataLog("cell is NULL\n");
+ dataLogF("cell is NULL\n");
CRASH();
}
if (!cell->structure()) {
- dataLog("cell at %p has a null structure\n" , cell);
+ dataLogF("cell at %p has a null structure\n" , cell);
CRASH();
}
@@ -353,7 +354,7 @@ void SlotVisitor::validate(JSCell* cell)
parentClassName = cell->structure()->structure()->JSCell::classInfo()->className;
if (cell->structure()->JSCell::classInfo())
ourClassName = cell->structure()->JSCell::classInfo()->className;
- dataLog("parent structure (%p <%s>) of cell at %p doesn't match cell's structure (%p <%s>)\n",
+ dataLogF("parent structure (%p <%s>) of cell at %p doesn't match cell's structure (%p <%s>)\n",
cell->structure()->structure(), parentClassName, cell, cell->structure(), ourClassName);
CRASH();
}
diff --git a/Source/JavaScriptCore/heap/SlotVisitor.h b/Source/JavaScriptCore/heap/SlotVisitor.h
index dcd4b75ef..53c7de64f 100644
--- a/Source/JavaScriptCore/heap/SlotVisitor.h
+++ b/Source/JavaScriptCore/heap/SlotVisitor.h
@@ -27,7 +27,7 @@
#define SlotVisitor_h
#include "HandleTypes.h"
-#include "MarkStackInlineMethods.h"
+#include "MarkStackInlines.h"
#include <wtf/text/StringHash.h>
@@ -36,6 +36,7 @@ namespace JSC {
class ConservativeRoots;
class GCThreadSharedData;
class Heap;
+template<typename T> class Weak;
template<typename T> class WriteBarrierBase;
template<typename T> class JITWriteBarrier;
@@ -56,6 +57,8 @@ public:
template<typename T>
void appendUnbarrieredPointer(T**);
void appendUnbarrieredValue(JSValue*);
+ template<typename T>
+ void appendUnbarrieredWeak(Weak<T>*);
void addOpaqueRoot(void*);
bool containsOpaqueRoot(void*);
diff --git a/Source/JavaScriptCore/heap/SlotVisitorInlineMethods.h b/Source/JavaScriptCore/heap/SlotVisitorInlines.h
index e5908bf36..ea8126f87 100644
--- a/Source/JavaScriptCore/heap/SlotVisitorInlineMethods.h
+++ b/Source/JavaScriptCore/heap/SlotVisitorInlines.h
@@ -23,12 +23,13 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef SlotVisitorInlineMethods_h
-#define SlotVisitorInlineMethods_h
+#ifndef SlotVisitorInlines_h
+#define SlotVisitorInlines_h
-#include "CopiedSpaceInlineMethods.h"
+#include "CopiedSpaceInlines.h"
#include "Options.h"
#include "SlotVisitor.h"
+#include "Weak.h"
namespace JSC {
@@ -66,6 +67,14 @@ ALWAYS_INLINE void SlotVisitor::append(JSCell** slot)
internalAppend(*slot);
}
+template<typename T>
+ALWAYS_INLINE void SlotVisitor::appendUnbarrieredWeak(Weak<T>* weak)
+{
+ ASSERT(weak);
+ if (weak->get())
+ internalAppend(weak->get());
+}
+
ALWAYS_INLINE void SlotVisitor::internalAppend(JSValue value)
{
if (!value || !value.isCell())
@@ -170,5 +179,5 @@ inline void SlotVisitor::copyLater(void* ptr, size_t bytes)
} // namespace JSC
-#endif // SlotVisitorInlineMethods_h
+#endif // SlotVisitorInlines_h
diff --git a/Source/JavaScriptCore/heap/Weak.h b/Source/JavaScriptCore/heap/Weak.h
index 3c3d1d0ce..efb2a9a56 100644
--- a/Source/JavaScriptCore/heap/Weak.h
+++ b/Source/JavaScriptCore/heap/Weak.h
@@ -151,6 +151,11 @@ template<typename T> inline WeakImpl* Weak<T>::hashTableDeletedValue()
return reinterpret_cast<WeakImpl*>(-1);
}
+template <typename T> inline bool operator==(const Weak<T>& lhs, const Weak<T>& rhs)
+{
+ return lhs.get() == rhs.get();
+}
+
// This function helps avoid modifying a weak table while holding an iterator into it. (Object allocation
// can run a finalizer that modifies the table. We avoid that by requiring a pre-constructed object as our value.)
template<typename Map, typename Key, typename Value> inline void weakAdd(Map& map, const Key& key, Value value)