Commit 5f16f890 authored by ggaren@apple.com's avatar ggaren@apple.com

2011-04-05 Geoffrey Garen <ggaren@apple.com>

        Reviewed by Oliver Hunt.

        Introduced the concept of opaque roots, in preparation for marking the DOM with them
        https://bugs.webkit.org/show_bug.cgi?id=57903

        * JavaScriptCore.exp: Who likes export files? I do!

        * collector/handles/HandleHeap.cpp:
        (JSC::isValidWeakHandle): Factored out a helper function for ASSERTs.

        (JSC::WeakHandleOwner::~WeakHandleOwner): Moved from header to avoid
        weak linkage problems.

        (JSC::WeakHandleOwner::isReachableFromOpaqueRoots): New callback.
        Currently unused.

        (JSC::WeakHandleOwner::finalize): Switched from pure virtual to a
        default empty implementation, since not all clients necessarily want
        or need non-trivial finalizers.

        (JSC::HandleHeap::markWeakHandles): Split updateWeakHandles into two
        passes. The first pass marks all reachable weak handles. The second pass
        finalizes all unreachable weak handles. This must be two passes because
        we don't know the set of finalizable weak handles until we're done
        marking all weak handles.

        (JSC::HandleHeap::finalizeWeakHandles): Use new helper function.

        * collector/handles/HandleHeap.h: Ditto.

        * runtime/Heap.cpp: 
        (JSC::Heap::destroy):
        (JSC::Heap::markRoots):
        (JSC::Heap::reset): Split out handle marking from handle finalization.

        * runtime/MarkStack.cpp:
        (JSC::MarkStack::reset):
        * runtime/MarkStack.h:
        (JSC::MarkStack::addOpaqueRoot):
        (JSC::MarkStack::containsOpaqueRoot):
        (JSC::MarkStack::opaqueRootCount):
        (JSC::HeapRootMarker::markStack): New helper functions for managing the
        set of opaque roots.

        * runtime/WeakGCMap.h:
        (JSC::WeakGCMap::finalize): Renamed to match parent class declaration.


git-svn-id: svn://svn.chromium.org/blink/trunk@83011 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent d51c24cf
2011-04-05 Geoffrey Garen <ggaren@apple.com>
Reviewed by Oliver Hunt.
Introduced the concept of opaque roots, in preparation for marking the DOM with them
https://bugs.webkit.org/show_bug.cgi?id=57903
* JavaScriptCore.exp: Who likes export files? I do!
* collector/handles/HandleHeap.cpp:
(JSC::isValidWeakHandle): Factored out a helper function for ASSERTs.
(JSC::WeakHandleOwner::~WeakHandleOwner): Moved from header to avoid
weak linkage problems.
(JSC::WeakHandleOwner::isReachableFromOpaqueRoots): New callback.
Currently unused.
(JSC::WeakHandleOwner::finalize): Switched from pure virtual to a
default empty implementation, since not all clients necessarily want
or need non-trivial finalizers.
(JSC::HandleHeap::markWeakHandles): Split updateWeakHandles into two
passes. The first pass marks all reachable weak handles. The second pass
finalizes all unreachable weak handles. This must be two passes because
we don't know the set of finalizable weak handles until we're done
marking all weak handles.
(JSC::HandleHeap::finalizeWeakHandles): Use new helper function.
* collector/handles/HandleHeap.h: Ditto.
* runtime/Heap.cpp:
(JSC::Heap::destroy):
(JSC::Heap::markRoots):
(JSC::Heap::reset): Split out handle marking from handle finalization.
* runtime/MarkStack.cpp:
(JSC::MarkStack::reset):
* runtime/MarkStack.h:
(JSC::MarkStack::addOpaqueRoot):
(JSC::MarkStack::containsOpaqueRoot):
(JSC::MarkStack::opaqueRootCount):
(JSC::HeapRootMarker::markStack): New helper functions for managing the
set of opaque roots.
* runtime/WeakGCMap.h:
(JSC::WeakGCMap::finalize): Renamed to match parent class declaration.
2011-04-05 Balazs Kelemen <kbalazs@webkit.org>
Reviewed by Darin Adler.
......
......@@ -169,6 +169,8 @@ __ZN3JSC14TimeoutChecker10didTimeOutEPNS_9ExecStateE
__ZN3JSC14TimeoutChecker5resetEv
__ZN3JSC14throwTypeErrorEPNS_9ExecStateE
__ZN3JSC15JSWrapperObject12markChildrenERNS_9MarkStackE
__ZN3JSC15WeakHandleOwner26isReachableFromOpaqueRootsENS_6HandleINS_7UnknownEEEPvRNS_9MarkStackE
__ZN3JSC15WeakHandleOwnerD2Ev
__ZN3JSC15createTypeErrorEPNS_9ExecStateERKNS_7UStringE
__ZN3JSC16InternalFunction12vtableAnchorEv
__ZN3JSC16InternalFunction4nameEPNS_9ExecStateE
......@@ -384,9 +386,9 @@ __ZN3WTF12createThreadEPFPvS0_ES0_PKc
__ZN3WTF12detachThreadEj
__ZN3WTF12isMainThreadEv
__ZN3WTF12randomNumberEv
__ZN3WTF13StringBuilder15reserveCapacityEj
__ZN3WTF13StringBuilder11reifyStringEv
__ZN3WTF13StringBuilder11shrinkToFitEv
__ZN3WTF13StringBuilder15reserveCapacityEj
__ZN3WTF13StringBuilder6appendEPKcj
__ZN3WTF13StringBuilder6appendEPKtj
__ZN3WTF13StringBuilder6resizeEj
......@@ -596,6 +598,7 @@ __ZTVN3JSC12StringObjectE
__ZTVN3JSC14JSGlobalObjectE
__ZTVN3JSC14ScopeChainNodeE
__ZTVN3JSC15JSWrapperObjectE
__ZTVN3JSC15WeakHandleOwnerE
__ZTVN3JSC16InternalFunctionE
__ZTVN3JSC16JSVariableObjectE
__ZTVN3JSC8DebuggerE
......
......@@ -24,13 +24,45 @@
*/
#include "config.h"
#include "HandleHeap.h"
#include "JSObject.h"
namespace JSC {
#if !ASSERT_DISABLED
static inline bool isValidWeakHandle(HandleSlot handle)
{
JSValue value = *handle;
if (!value || !value.isCell())
return false;
JSCell* cell = value.asCell();
if (!cell || !cell->structure())
return false;
#if ENABLE(JSC_ZOMBIES)
if (cell->isZombie())
return false;
#endif
return true;
}
#endif
WeakHandleOwner::~WeakHandleOwner()
{
}
bool WeakHandleOwner::isReachableFromOpaqueRoots(Handle<Unknown>, void*, MarkStack&)
{
return false;
}
void WeakHandleOwner::finalize(Handle<Unknown>, void*)
{
}
HandleHeap::HandleHeap(JSGlobalData* globalData)
: m_globalData(globalData)
, m_nextToFinalize(0)
......@@ -55,21 +87,41 @@ void HandleHeap::markStrongHandles(HeapRootMarker& heapRootMarker)
heapRootMarker.mark(node->slot());
}
void HandleHeap::updateWeakHandles()
void HandleHeap::markWeakHandles(HeapRootMarker& heapRootMarker)
{
MarkStack& markStack = heapRootMarker.markStack();
int oldCount;
do {
oldCount = markStack.opaqueRootCount();
Node* end = m_weakList.end();
for (Node* node = m_weakList.begin(); node != end; node = node->next()) {
ASSERT(isValidWeakHandle(node->slot()));
JSCell* cell = node->slot()->asCell();
if (Heap::isMarked(cell))
continue;
WeakHandleOwner* weakOwner = node->weakOwner();
if (!weakOwner)
continue;
if (!weakOwner->isReachableFromOpaqueRoots(Handle<Unknown>::wrapSlot(node->slot()), node->weakOwnerContext(), markStack))
continue;
heapRootMarker.mark(node->slot());
}
} while (oldCount != markStack.opaqueRootCount()); // If the set of opaque roots has grown, more handles may have become reachable.
}
void HandleHeap::finalizeWeakHandles()
{
Node* end = m_weakList.end();
for (Node* node = m_weakList.begin(); node != end; node = m_nextToFinalize) {
m_nextToFinalize = node->next();
JSValue value = *node->slot();
ASSERT(value);
JSCell* cell = value.asCell();
ASSERT(cell && cell->structure());
#if ENABLE(JSC_ZOMBIES)
ASSERT(!cell->isZombie());
#endif
ASSERT(isValidWeakHandle(node->slot()));
JSCell* cell = node->slot()->asCell();
if (Heap::isMarked(cell))
continue;
......
......@@ -34,14 +34,16 @@
namespace JSC {
class HandleHeap;
class HeapRootMarker;
class JSGlobalData;
class JSValue;
class HeapRootMarker;
class MarkStack;
class WeakHandleOwner {
public:
virtual void finalize(Handle<Unknown>, void*) = 0;
virtual ~WeakHandleOwner() {}
virtual ~WeakHandleOwner();
virtual bool isReachableFromOpaqueRoots(Handle<Unknown>, void* context, MarkStack&);
virtual void finalize(Handle<Unknown>, void* context);
};
class HandleHeap {
......@@ -56,7 +58,8 @@ public:
void makeWeak(HandleSlot, WeakHandleOwner* = 0, void* context = 0);
void markStrongHandles(HeapRootMarker&);
void updateWeakHandles();
void markWeakHandles(HeapRootMarker&);
void finalizeWeakHandles();
void writeBarrier(HandleSlot, const JSValue&);
......
......@@ -82,7 +82,7 @@ void Heap::destroy()
delete m_markListSet;
m_markListSet = 0;
m_markedSpace.clearMarks();
m_handleHeap.updateWeakHandles();
m_handleHeap.finalizeWeakHandles();
m_markedSpace.destroy();
m_globalData = 0;
......@@ -242,14 +242,15 @@ void Heap::markRoots()
m_handleHeap.markStrongHandles(heapRootMarker);
m_handleStack.mark(heapRootMarker);
m_handleHeap.markWeakHandles(heapRootMarker);
markStack.drain();
// Mark the small strings cache last, since it will clear itself if nothing
// else has marked it.
m_globalData->smallStrings.markChildren(heapRootMarker);
markStack.drain();
markStack.compact();
m_handleHeap.updateWeakHandles();
markStack.reset();
m_operationInProgress = NoOperation;
}
......@@ -369,6 +370,7 @@ void Heap::reset(SweepToggle sweepToggle)
JAVASCRIPTCORE_GC_BEGIN();
markRoots();
m_handleHeap.finalizeWeakHandles();
JAVASCRIPTCORE_GC_MARKED();
......
......@@ -38,11 +38,12 @@ namespace JSC {
size_t MarkStack::s_pageSize = 0;
void MarkStack::compact()
void MarkStack::reset()
{
ASSERT(s_pageSize);
m_values.shrinkAllocation(s_pageSize);
m_markSets.shrinkAllocation(s_pageSize);
m_opaqueRoots.clear();
}
void MarkStack::append(ConservativeRoots& conservativeRoots)
......
......@@ -29,6 +29,7 @@
#include "JSValue.h"
#include "Register.h"
#include "WriteBarrier.h"
#include <wtf/HashSet.h>
#include <wtf/Vector.h>
#include <wtf/Noncopyable.h>
#include <wtf/OSAllocator.h>
......@@ -81,8 +82,12 @@ namespace JSC {
void append(ConservativeRoots&);
bool addOpaqueRoot(void* root) { return m_opaqueRoots.add(root).second; }
bool containsOpaqueRoot(void* root) { return m_opaqueRoots.contains(root); }
int opaqueRootCount() { return m_opaqueRoots.size(); }
void drain();
void compact();
void reset();
private:
friend class HeapRootMarker; // Allowed to mark a JSValue* or JSCell** directly.
......@@ -198,6 +203,7 @@ namespace JSC {
MarkStackArray<MarkSet> m_markSets;
MarkStackArray<JSCell*> m_values;
static size_t s_pageSize;
HashSet<void*> m_opaqueRoots; // Handle-owning data structures not visible to the garbage collector.
#if !ASSERT_DISABLED
public:
......@@ -274,6 +280,8 @@ namespace JSC {
void mark(JSValue*, size_t);
void mark(JSString**);
void mark(JSCell**);
MarkStack& markStack();
private:
MarkStack& m_markStack;
......@@ -304,6 +312,11 @@ namespace JSC {
m_markStack.append(slot);
}
inline MarkStack& HeapRootMarker::markStack()
{
return m_markStack;
}
} // namespace JSC
#endif
......@@ -122,9 +122,9 @@ public:
}
private:
virtual void finalize(Handle<Unknown>, void* key)
virtual void finalize(Handle<Unknown>, void* context)
{
HandleSlot slot = m_map.take(static_cast<KeyType>(key));
HandleSlot slot = m_map.take(static_cast<KeyType>(context));
ASSERT(slot);
HandleHeap::heapFor(slot)->deallocate(slot);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment