summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/heap/CopiedBlock.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/heap/CopiedBlock.h')
-rw-r--r--Source/JavaScriptCore/heap/CopiedBlock.h120
1 files changed, 62 insertions, 58 deletions
diff --git a/Source/JavaScriptCore/heap/CopiedBlock.h b/Source/JavaScriptCore/heap/CopiedBlock.h
index 86cca8cbe..dd3b44532 100644
--- a/Source/JavaScriptCore/heap/CopiedBlock.h
+++ b/Source/JavaScriptCore/heap/CopiedBlock.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,33 +26,35 @@
#ifndef CopiedBlock_h
#define CopiedBlock_h
-#include "BlockAllocator.h"
#include "CopyWorkList.h"
-#include "HeapBlock.h"
#include "JSCJSValue.h"
#include "Options.h"
-#include <wtf/Atomics.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/PassOwnPtr.h>
+#include <wtf/DoublyLinkedList.h>
+#include <wtf/Lock.h>
namespace JSC {
class CopiedSpace;
-class CopiedBlock : public HeapBlock<CopiedBlock> {
+class CopiedBlock : public DoublyLinkedListNode<CopiedBlock> {
+ friend class WTF::DoublyLinkedListNode<CopiedBlock>;
friend class CopiedSpace;
friend class CopiedAllocator;
public:
- static CopiedBlock* create(DeadBlock*);
- static CopiedBlock* createNoZeroFill(DeadBlock*);
+ static CopiedBlock* create(Heap&, size_t = blockSize);
+ static CopiedBlock* createNoZeroFill(Heap&, size_t = blockSize);
+ static void destroy(Heap&, CopiedBlock*);
void pin();
bool isPinned();
+ bool isOld();
bool isOversize();
+ void didPromote();
unsigned liveBytes();
- void reportLiveBytes(JSCell*, unsigned);
+ void reportLiveBytes(LockHolder&, JSCell*, CopyToken, unsigned);
+ void reportLiveBytesDuringCopying(unsigned);
void didSurviveGC();
void didEvacuateBytes(unsigned);
bool shouldEvacuate();
@@ -81,79 +83,65 @@ public:
bool hasWorkList();
CopyWorkList& workList();
+ Lock& workListLock() { return m_workListLock; }
private:
- CopiedBlock(Region*);
+ CopiedBlock(size_t);
void zeroFillWilderness(); // Can be called at any time to zero-fill to the end of the block.
-#if ENABLE(PARALLEL_GC)
- SpinLock m_workListLock;
-#endif
- OwnPtr<CopyWorkList> m_workList;
+ void checkConsistency();
- size_t m_remaining;
- uintptr_t m_isPinned;
- unsigned m_liveBytes;
-};
-
-inline CopiedBlock* CopiedBlock::createNoZeroFill(DeadBlock* block)
-{
- Region* region = block->region();
- return new(NotNull, block) CopiedBlock(region);
-}
+ CopiedBlock* m_prev;
+ CopiedBlock* m_next;
-inline CopiedBlock* CopiedBlock::create(DeadBlock* block)
-{
- CopiedBlock* newBlock = createNoZeroFill(block);
- newBlock->zeroFillWilderness();
- return newBlock;
-}
+ size_t m_capacity;
-inline void CopiedBlock::zeroFillWilderness()
-{
-#if USE(JSVALUE64)
- memset(wilderness(), 0, wildernessSize());
-#else
- JSValue emptyValue;
- JSValue* limit = reinterpret_cast_ptr<JSValue*>(wildernessEnd());
- for (JSValue* currentValue = reinterpret_cast_ptr<JSValue*>(wilderness()); currentValue < limit; currentValue++)
- *currentValue = emptyValue;
-#endif
-}
+ Lock m_workListLock;
+ std::unique_ptr<CopyWorkList> m_workList;
-inline CopiedBlock::CopiedBlock(Region* region)
- : HeapBlock<CopiedBlock>(region)
- , m_remaining(payloadCapacity())
- , m_isPinned(false)
- , m_liveBytes(0)
-{
-#if ENABLE(PARALLEL_GC)
- m_workListLock.Init();
+ size_t m_remaining;
+ bool m_isPinned : 1;
+ bool m_isOld : 1;
+ unsigned m_liveBytes;
+#ifndef NDEBUG
+ unsigned m_liveObjects;
#endif
- ASSERT(is8ByteAligned(reinterpret_cast<void*>(m_remaining)));
-}
+};
inline void CopiedBlock::didSurviveGC()
{
+ checkConsistency();
+ ASSERT(isOld());
m_liveBytes = 0;
+#ifndef NDEBUG
+ m_liveObjects = 0;
+#endif
m_isPinned = false;
if (m_workList)
- m_workList.clear();
+ m_workList = nullptr;
}
inline void CopiedBlock::didEvacuateBytes(unsigned bytes)
{
ASSERT(m_liveBytes >= bytes);
+ ASSERT(m_liveObjects);
+ checkConsistency();
m_liveBytes -= bytes;
+#ifndef NDEBUG
+ m_liveObjects--;
+#endif
+ checkConsistency();
}
inline bool CopiedBlock::canBeRecycled()
{
+ checkConsistency();
return !m_liveBytes;
}
inline bool CopiedBlock::shouldEvacuate()
{
+ checkConsistency();
return static_cast<double>(m_liveBytes) / static_cast<double>(payloadCapacity()) <= Options::minCopiedBlockUtilization();
}
@@ -161,7 +149,7 @@ inline void CopiedBlock::pin()
{
m_isPinned = true;
if (m_workList)
- m_workList.clear();
+ m_workList = nullptr;
}
inline bool CopiedBlock::isPinned()
@@ -169,24 +157,35 @@ inline bool CopiedBlock::isPinned()
return m_isPinned;
}
+inline bool CopiedBlock::isOld()
+{
+ return m_isOld;
+}
+
+inline void CopiedBlock::didPromote()
+{
+ m_isOld = true;
+}
+
inline bool CopiedBlock::isOversize()
{
- return region()->isCustomSize();
+ return m_capacity != blockSize;
}
inline unsigned CopiedBlock::liveBytes()
{
+ checkConsistency();
return m_liveBytes;
}
inline char* CopiedBlock::payload()
{
- return reinterpret_cast<char*>(this) + ((sizeof(CopiedBlock) + 7) & ~7);
+ return reinterpret_cast<char*>(this) + WTF::roundUpToMultipleOf<sizeof(double)>(sizeof(CopiedBlock));
}
inline char* CopiedBlock::payloadEnd()
{
- return reinterpret_cast<char*>(this) + region()->blockSize();
+ return reinterpret_cast<char*>(this) + m_capacity;
}
inline size_t CopiedBlock::payloadCapacity()
@@ -231,7 +230,7 @@ inline size_t CopiedBlock::size()
inline size_t CopiedBlock::capacity()
{
- return region()->blockSize();
+ return m_capacity;
}
inline bool CopiedBlock::hasWorkList()
@@ -244,6 +243,11 @@ inline CopyWorkList& CopiedBlock::workList()
return *m_workList;
}
+inline void CopiedBlock::checkConsistency()
+{
+ ASSERT(!!m_liveBytes == !!m_liveObjects);
+}
+
} // namespace JSC
#endif