summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/heap
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-11-07 11:22:47 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2012-11-07 11:22:47 +0100
commitcfd86b747d32ac22246a1aa908eaa720c63a88c1 (patch)
tree24d68c6f61c464ecba1e05670b80390ea3b0e50c /Source/JavaScriptCore/heap
parent69d7c744c9de19d152dbe2d8e46eb7dfd4511d1a (diff)
downloadqtwebkit-cfd86b747d32ac22246a1aa908eaa720c63a88c1.tar.gz
Imported WebKit commit 20271caf2e2c016d5cef40184cddeefeac4f1876 (http://svn.webkit.org/repository/webkit/trunk@133733)
New snapshot that contains all previous fixes as well as build fix for latest QtMultimedia API changes.
Diffstat (limited to 'Source/JavaScriptCore/heap')
-rw-r--r--Source/JavaScriptCore/heap/Heap.cpp5
-rw-r--r--Source/JavaScriptCore/heap/Heap.h6
-rw-r--r--Source/JavaScriptCore/heap/MarkedAllocator.h12
-rw-r--r--Source/JavaScriptCore/heap/MarkedBlock.cpp27
-rw-r--r--Source/JavaScriptCore/heap/MarkedBlock.h26
-rw-r--r--Source/JavaScriptCore/heap/SlotVisitor.cpp6
-rw-r--r--Source/JavaScriptCore/heap/WeakBlock.cpp4
7 files changed, 73 insertions, 13 deletions
diff --git a/Source/JavaScriptCore/heap/Heap.cpp b/Source/JavaScriptCore/heap/Heap.cpp
index cd3393aa2..c455fc2b1 100644
--- a/Source/JavaScriptCore/heap/Heap.cpp
+++ b/Source/JavaScriptCore/heap/Heap.cpp
@@ -36,6 +36,7 @@
#include "JSLock.h"
#include "JSONObject.h"
#include "Tracing.h"
+#include "UnlinkedCodeBlock.h"
#include "WeakSetInlines.h"
#include <algorithm>
#include <wtf/RAMSize.h>
@@ -484,13 +485,13 @@ void Heap::markRoots(bool fullGC)
}
}
#endif
-
+
if (m_globalData->codeBlocksBeingCompiled.size()) {
GCPHASE(VisitActiveCodeBlock);
for (size_t i = 0; i < m_globalData->codeBlocksBeingCompiled.size(); i++)
m_globalData->codeBlocksBeingCompiled[i]->visitAggregate(visitor);
}
-
+
{
GCPHASE(VisitMachineRoots);
MARK_LOG_ROOT(visitor, "C++ Stack");
diff --git a/Source/JavaScriptCore/heap/Heap.h b/Source/JavaScriptCore/heap/Heap.h
index 88dc201a4..51cebdc0e 100644
--- a/Source/JavaScriptCore/heap/Heap.h
+++ b/Source/JavaScriptCore/heap/Heap.h
@@ -86,6 +86,7 @@ namespace JSC {
// our scan to run faster.
static const unsigned s_timeCheckResolution = 16;
+ static bool isLive(const void*);
static bool isMarked(const void*);
static bool testAndSetMarked(const void*);
static void setMarked(const void*);
@@ -305,6 +306,11 @@ namespace JSC {
return heap(v.asCell());
}
+ inline bool Heap::isLive(const void* cell)
+ {
+ return MarkedBlock::blockFor(cell)->isLiveCell(cell);
+ }
+
inline bool Heap::isMarked(const void* cell)
{
return MarkedBlock::blockFor(cell)->isMarked(cell);
diff --git a/Source/JavaScriptCore/heap/MarkedAllocator.h b/Source/JavaScriptCore/heap/MarkedAllocator.h
index 13bd8e493..867481fe3 100644
--- a/Source/JavaScriptCore/heap/MarkedAllocator.h
+++ b/Source/JavaScriptCore/heap/MarkedAllocator.h
@@ -74,10 +74,18 @@ inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t c
inline void* MarkedAllocator::allocate(size_t bytes)
{
MarkedBlock::FreeCell* head = m_freeList.head;
- if (UNLIKELY(!head))
- return allocateSlowCase(bytes);
+ if (UNLIKELY(!head)) {
+ void* result = allocateSlowCase(bytes);
+#ifndef NDEBUG
+ memset(result, 0xCD, bytes);
+#endif
+ return result;
+ }
m_freeList.head = head->next;
+#ifndef NDEBUG
+ memset(head, 0xCD, bytes);
+#endif
return head;
}
diff --git a/Source/JavaScriptCore/heap/MarkedBlock.cpp b/Source/JavaScriptCore/heap/MarkedBlock.cpp
index 70a24b6ae..9a036f87c 100644
--- a/Source/JavaScriptCore/heap/MarkedBlock.cpp
+++ b/Source/JavaScriptCore/heap/MarkedBlock.cpp
@@ -78,7 +78,7 @@ MarkedBlock::FreeList MarkedBlock::specializedSweep()
FreeCell* head = 0;
size_t count = 0;
for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) {
- if (blockState == Marked && m_marks.get(i))
+ if (blockState == Marked && (m_marks.get(i) || (m_newlyAllocated && m_newlyAllocated->get(i))))
continue;
JSCell* cell = reinterpret_cast_ptr<JSCell*>(&atoms()[i]);
@@ -94,6 +94,11 @@ MarkedBlock::FreeList MarkedBlock::specializedSweep()
}
}
+ // We only want to discard the newlyAllocated bits if we're creating a FreeList,
+ // otherwise we would lose information on what's currently alive.
+ if (sweepMode == SweepToFreeList && m_newlyAllocated)
+ m_newlyAllocated.clear();
+
m_state = ((sweepMode == SweepToFreeList) ? FreeListed : Marked);
return FreeList(head, count * cellSize());
}
@@ -138,12 +143,21 @@ MarkedBlock::FreeList MarkedBlock::sweepHelper(SweepMode sweepMode)
return FreeList();
}
-class SetAllMarksFunctor : public MarkedBlock::VoidFunctor {
+class SetNewlyAllocatedFunctor : public MarkedBlock::VoidFunctor {
public:
+ SetNewlyAllocatedFunctor(MarkedBlock* block)
+ : m_block(block)
+ {
+ }
+
void operator()(JSCell* cell)
{
- MarkedBlock::blockFor(cell)->setMarked(cell);
+ ASSERT(MarkedBlock::blockFor(cell) == m_block);
+ m_block->setNewlyAllocated(cell);
}
+
+private:
+ MarkedBlock* m_block;
};
void MarkedBlock::canonicalizeCellLivenessData(const FreeList& freeList)
@@ -168,14 +182,17 @@ void MarkedBlock::canonicalizeCellLivenessData(const FreeList& freeList)
// allocated from our free list are not currently marked, so we need another
// way to tell what's live vs dead.
- SetAllMarksFunctor functor;
+ ASSERT(!m_newlyAllocated);
+ m_newlyAllocated = adoptPtr(new WTF::Bitmap<atomsPerBlock>());
+
+ SetNewlyAllocatedFunctor functor(this);
forEachCell(functor);
FreeCell* next;
for (FreeCell* current = head; current; current = next) {
next = current->next;
reinterpret_cast<JSCell*>(current)->zap();
- clearMarked(current);
+ clearNewlyAllocated(current);
}
m_state = Marked;
diff --git a/Source/JavaScriptCore/heap/MarkedBlock.h b/Source/JavaScriptCore/heap/MarkedBlock.h
index 31bf60b9f..f2f2a720d 100644
--- a/Source/JavaScriptCore/heap/MarkedBlock.h
+++ b/Source/JavaScriptCore/heap/MarkedBlock.h
@@ -159,6 +159,10 @@ namespace JSC {
void setMarked(const void*);
void clearMarked(const void*);
+ bool isNewlyAllocated(const void*);
+ void setNewlyAllocated(const void*);
+ void clearNewlyAllocated(const void*);
+
bool needsSweeping();
#if ENABLE(GGC)
@@ -218,6 +222,8 @@ namespace JSC {
#else
WTF::Bitmap<atomsPerBlock, WTF::BitmapNotAtomic> m_marks;
#endif
+ OwnPtr<WTF::Bitmap<atomsPerBlock> > m_newlyAllocated;
+
DestructorType m_destructorType;
MarkedAllocator* m_allocator;
BlockState m_state;
@@ -313,6 +319,7 @@ namespace JSC {
ASSERT(m_state != New && m_state != FreeListed);
m_marks.clearAll();
+ m_newlyAllocated.clear();
// This will become true at the end of the mark phase. We set it now to
// avoid an extra pass to do so later.
@@ -326,7 +333,7 @@ namespace JSC {
inline bool MarkedBlock::isEmpty()
{
- return m_marks.isEmpty() && m_weakSet.isEmpty();
+ return m_marks.isEmpty() && m_weakSet.isEmpty() && (!m_newlyAllocated || m_newlyAllocated->isEmpty());
}
inline size_t MarkedBlock::cellSize()
@@ -375,6 +382,21 @@ namespace JSC {
m_marks.clear(atomNumber(p));
}
+ inline bool MarkedBlock::isNewlyAllocated(const void* p)
+ {
+ return m_newlyAllocated->get(atomNumber(p));
+ }
+
+ inline void MarkedBlock::setNewlyAllocated(const void* p)
+ {
+ m_newlyAllocated->set(atomNumber(p));
+ }
+
+ inline void MarkedBlock::clearNewlyAllocated(const void* p)
+ {
+ m_newlyAllocated->clear(atomNumber(p));
+ }
+
inline bool MarkedBlock::isLive(const JSCell* cell)
{
switch (m_state) {
@@ -382,7 +404,7 @@ namespace JSC {
return true;
case Marked:
- return m_marks.get(atomNumber(cell));
+ return m_marks.get(atomNumber(cell)) || (m_newlyAllocated && isNewlyAllocated(cell));
case New:
case FreeListed:
diff --git a/Source/JavaScriptCore/heap/SlotVisitor.cpp b/Source/JavaScriptCore/heap/SlotVisitor.cpp
index 7a30debda..3919705d0 100644
--- a/Source/JavaScriptCore/heap/SlotVisitor.cpp
+++ b/Source/JavaScriptCore/heap/SlotVisitor.cpp
@@ -294,6 +294,8 @@ ALWAYS_INLINE void SlotVisitor::internalAppend(JSValue* slot)
if (!cell)
return;
+ validate(cell);
+
if (m_shouldHashConst && cell->isString()) {
JSString* string = jsCast<JSString*>(cell);
if (string->shouldTryHashConst() && string->tryHashConstLock()) {
@@ -355,6 +357,10 @@ void SlotVisitor::validate(JSCell* cell)
cell->structure()->structure(), parentClassName, cell, cell->structure(), ourClassName);
CRASH();
}
+
+ // Make sure we can walk the ClassInfo chain
+ const ClassInfo* info = cell->classInfo();
+ do { } while ((info = info->parentClass));
}
#else
void SlotVisitor::validate(JSCell*)
diff --git a/Source/JavaScriptCore/heap/WeakBlock.cpp b/Source/JavaScriptCore/heap/WeakBlock.cpp
index 13039e702..99e306b85 100644
--- a/Source/JavaScriptCore/heap/WeakBlock.cpp
+++ b/Source/JavaScriptCore/heap/WeakBlock.cpp
@@ -102,7 +102,7 @@ void WeakBlock::visit(HeapRootVisitor& heapRootVisitor)
continue;
const JSValue& jsValue = weakImpl->jsValue();
- if (Heap::isMarked(jsValue.asCell()))
+ if (Heap::isLive(jsValue.asCell()))
continue;
WeakHandleOwner* weakHandleOwner = weakImpl->weakHandleOwner();
@@ -127,7 +127,7 @@ void WeakBlock::reap()
if (weakImpl->state() > WeakImpl::Dead)
continue;
- if (Heap::isMarked(weakImpl->jsValue().asCell())) {
+ if (Heap::isLive(weakImpl->jsValue().asCell())) {
ASSERT(weakImpl->state() == WeakImpl::Live);
continue;
}