Commit 40c8716a authored by ggaren@apple.com's avatar ggaren@apple.com

2011-03-16 Geoffrey Garen <ggaren@apple.com>

        Reviewed by Oliver Hunt.

        Some conservative root gathering cleanup
        https://bugs.webkit.org/show_bug.cgi?id=56447
        
        SunSpider says 0.5% - 1.8% faster.

        * interpreter/RegisterFile.cpp:
        (JSC::RegisterFile::gatherConservativeRoots):
        * interpreter/RegisterFile.h: New helper function for doing the
        conservative gathering of the register file. It's still conservative,
        since the register file may contain uninitialized values, but it's
        moving-safe, because it only visits values tagged as pointers, so there's
        no risk of mistaking an integer for a pointer and accidentally changing it.

        * runtime/ConservativeSet.cpp:
        (JSC::ConservativeRoots::add):
        * runtime/ConservativeSet.h: Added a single-value add function, used above.

        * runtime/Heap.cpp:
        (JSC::Heap::markRoots): Separated machine stack conservative roots from
        register file conservative roots because machine stack roots must be
        pinned, but register file roots need not be pinned.
        
        Adopted new interface for passing the current stack extent to the machine
        stack root gathering routine. This allows us to exclude marking-related
        data structures on the stack, and thus avoid double-marking the set of
        machine roots.

        * runtime/MachineStackMarker.cpp:
        (JSC::MachineThreads::gatherFromCurrentThread):
        (JSC::MachineThreads::gatherConservativeRoots):
        * runtime/MachineStackMarker.h: Added new interface, described above.

        * runtime/MarkedBlock.h:
        (JSC::MarkedBlock::firstAtom):
        * wtf/StdLibExtras.h:
        (WTF::roundUpToMultipleOf): Moved roundUpToMultipleOf so it could be used
        by MachineStacks.


git-svn-id: svn://svn.chromium.org/blink/trunk@81262 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 4eb5911e
2011-03-16 Geoffrey Garen <ggaren@apple.com>
Reviewed by Oliver Hunt.
Some conservative root gathering cleanup
https://bugs.webkit.org/show_bug.cgi?id=56447
SunSpider says 0.5% - 1.8% faster.
* interpreter/RegisterFile.cpp:
(JSC::RegisterFile::gatherConservativeRoots):
* interpreter/RegisterFile.h: New helper function for doing the
conservative gathering of the register file. It's still conservative,
since the register file may contain uninitialized values, but it's
moving-safe, because it only visits values tagged as pointers, so there's
no risk of mistaking an integer for a pointer and accidentally changing it.
* runtime/ConservativeSet.cpp:
(JSC::ConservativeRoots::add):
* runtime/ConservativeSet.h: Added a single-value add function, used above.
* runtime/Heap.cpp:
(JSC::Heap::markRoots): Separated machine stack conservative roots from
register file conservative roots because machine stack roots must be
pinned, but register file roots need not be pinned.
Adopted new interface for passing the current stack extent to the machine
stack root gathering routine. This allows us to exclude marking-related
data structures on the stack, and thus avoid double-marking the set of
machine roots.
* runtime/MachineStackMarker.cpp:
(JSC::MachineThreads::gatherFromCurrentThread):
(JSC::MachineThreads::gatherConservativeRoots):
* runtime/MachineStackMarker.h: Added new interface, described above.
* runtime/MarkedBlock.h:
(JSC::MarkedBlock::firstAtom):
* wtf/StdLibExtras.h:
(WTF::roundUpToMultipleOf): Moved roundUpToMultipleOf so it could be used
by MachineStacks.
2011-03-16 Geoffrey Garen <ggaren@apple.com> 2011-03-16 Geoffrey Garen <ggaren@apple.com>
Reviewed by Oliver Hunt. Reviewed by Oliver Hunt.
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "config.h" #include "config.h"
#include "RegisterFile.h" #include "RegisterFile.h"
#include "ConservativeSet.h"
#include "Interpreter.h" #include "Interpreter.h"
#include "JSGlobalData.h" #include "JSGlobalData.h"
#include "JSGlobalObject.h" #include "JSGlobalObject.h"
...@@ -51,6 +52,16 @@ RegisterFile::~RegisterFile() ...@@ -51,6 +52,16 @@ RegisterFile::~RegisterFile()
m_reservation.deallocate(); m_reservation.deallocate();
} }
void RegisterFile::gatherConservativeRoots(ConservativeRoots& conservativeRoots)
{
for (Register* it = start(); it != end(); ++it) {
JSValue v = it->jsValue();
if (!v.isCell())
continue;
conservativeRoots.add(v.asCell());
}
}
void RegisterFile::releaseExcessCapacity() void RegisterFile::releaseExcessCapacity()
{ {
m_reservation.decommit(m_start, reinterpret_cast<intptr_t>(m_commitEnd) - reinterpret_cast<intptr_t>(m_start)); m_reservation.decommit(m_start, reinterpret_cast<intptr_t>(m_commitEnd) - reinterpret_cast<intptr_t>(m_start));
......
...@@ -113,6 +113,8 @@ namespace JSC { ...@@ -113,6 +113,8 @@ namespace JSC {
RegisterFile(JSGlobalData&, size_t capacity = defaultCapacity, size_t maxGlobals = defaultMaxGlobals); RegisterFile(JSGlobalData&, size_t capacity = defaultCapacity, size_t maxGlobals = defaultMaxGlobals);
~RegisterFile(); ~RegisterFile();
void gatherConservativeRoots(ConservativeRoots&);
Register* start() const { return m_start; } Register* start() const { return m_start; }
Register* end() const { return m_end; } Register* end() const { return m_end; }
......
...@@ -26,8 +26,6 @@ ...@@ -26,8 +26,6 @@
#include "config.h" #include "config.h"
#include "ConservativeSet.h" #include "ConservativeSet.h"
#include "Heap.h"
namespace JSC { namespace JSC {
inline bool isPointerAligned(void* p) inline bool isPointerAligned(void* p)
...@@ -53,15 +51,8 @@ void ConservativeRoots::add(void* begin, void* end) ...@@ -53,15 +51,8 @@ void ConservativeRoots::add(void* begin, void* end)
ASSERT(isPointerAligned(begin)); ASSERT(isPointerAligned(begin));
ASSERT(isPointerAligned(end)); ASSERT(isPointerAligned(end));
for (char** it = static_cast<char**>(begin); it != static_cast<char**>(end); ++it) { for (char** it = static_cast<char**>(begin); it != static_cast<char**>(end); ++it)
if (!m_heap->contains(*it)) add(*it);
continue;
if (m_size == m_capacity)
grow();
m_roots[m_size++] = reinterpret_cast<JSCell*>(*it);
}
} }
} // namespace JSC } // namespace JSC
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#ifndef ConservativeRoots_h #ifndef ConservativeRoots_h
#define ConservativeRoots_h #define ConservativeRoots_h
#include "Heap.h"
#include <wtf/OSAllocator.h> #include <wtf/OSAllocator.h>
#include <wtf/Vector.h> #include <wtf/Vector.h>
...@@ -41,6 +42,7 @@ public: ...@@ -41,6 +42,7 @@ public:
ConservativeRoots(Heap*); ConservativeRoots(Heap*);
~ConservativeRoots(); ~ConservativeRoots();
void add(void*);
void add(void* begin, void* end); void add(void* begin, void* end);
size_t size(); size_t size();
...@@ -73,6 +75,17 @@ inline ConservativeRoots::~ConservativeRoots() ...@@ -73,6 +75,17 @@ inline ConservativeRoots::~ConservativeRoots()
OSAllocator::decommitAndRelease(m_roots, m_capacity * sizeof(JSCell*)); OSAllocator::decommitAndRelease(m_roots, m_capacity * sizeof(JSCell*));
} }
inline void ConservativeRoots::add(void* p)
{
if (!m_heap->contains(p))
return;
if (m_size == m_capacity)
grow();
m_roots[m_size++] = reinterpret_cast<JSCell*>(p);
}
inline size_t ConservativeRoots::size() inline size_t ConservativeRoots::size()
{ {
return m_size; return m_size;
......
...@@ -199,25 +199,32 @@ void Heap::markRoots() ...@@ -199,25 +199,32 @@ void Heap::markRoots()
} }
#endif #endif
void* dummy;
ASSERT(m_operationInProgress == NoOperation); ASSERT(m_operationInProgress == NoOperation);
if (m_operationInProgress != NoOperation) if (m_operationInProgress != NoOperation)
CRASH(); CRASH();
m_operationInProgress = Collection; m_operationInProgress = Collection;
// We gather the conservative set before clearing mark bits, because MarkStack& markStack = m_markStack;
HeapRootMarker heapRootMarker(markStack);
// We gather conservative roots before clearing mark bits because
// conservative gathering uses the mark bits from our last mark pass to // conservative gathering uses the mark bits from our last mark pass to
// determine whether a reference is valid. // determine whether a reference is valid.
ConservativeRoots conservativeRoots(this); ConservativeRoots machineThreadRoots(this);
m_machineThreads.gatherConservativeRoots(conservativeRoots); m_machineThreads.gatherConservativeRoots(machineThreadRoots, &dummy);
conservativeRoots.add(registerFile().start(), registerFile().end());
ConservativeRoots registerFileRoots(this);
registerFile().gatherConservativeRoots(registerFileRoots);
m_markedSpace.clearMarks(); m_markedSpace.clearMarks();
MarkStack& markStack = m_markStack; markStack.append(machineThreadRoots);
HeapRootMarker heapRootMarker(markStack); markStack.drain();
markStack.append(conservativeRoots); markStack.append(registerFileRoots);
markStack.drain(); markStack.drain();
markProtectedObjects(heapRootMarker); markProtectedObjects(heapRootMarker);
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "JSGlobalData.h" #include "JSGlobalData.h"
#include <setjmp.h> #include <setjmp.h>
#include <stdlib.h> #include <stdlib.h>
#include <wtf/StdLibExtras.h>
#if USE(PTHREAD_BASED_QT) && !defined(WTF_USE_PTHREADS) #if USE(PTHREAD_BASED_QT) && !defined(WTF_USE_PTHREADS)
#define WTF_USE_PTHREADS 1 #define WTF_USE_PTHREADS 1
...@@ -84,6 +85,8 @@ ...@@ -84,6 +85,8 @@
#endif #endif
using namespace WTF;
namespace JSC { namespace JSC {
static inline void swapIfBackwards(void*& begin, void*& end) static inline void swapIfBackwards(void*& begin, void*& end)
...@@ -244,21 +247,13 @@ void MachineThreads::removeCurrentThread() ...@@ -244,21 +247,13 @@ void MachineThreads::removeCurrentThread()
#endif #endif
void NEVER_INLINE MachineThreads::gatherFromCurrentThreadInternal(ConservativeRoots& conservativeRoots)
{
void* begin = m_heap->globalData()->stack().current();
void* end = m_heap->globalData()->stack().origin();
swapIfBackwards(begin, end);
conservativeRoots.add(begin, end);
}
#if COMPILER(GCC) #if COMPILER(GCC)
#define REGISTER_BUFFER_ALIGNMENT __attribute__ ((aligned (sizeof(void*)))) #define REGISTER_BUFFER_ALIGNMENT __attribute__ ((aligned (sizeof(void*))))
#else #else
#define REGISTER_BUFFER_ALIGNMENT #define REGISTER_BUFFER_ALIGNMENT
#endif #endif
void MachineThreads::gatherFromCurrentThread(ConservativeRoots& conservativeRoots) void MachineThreads::gatherFromCurrentThread(ConservativeRoots& conservativeRoots, void* stackCurrent)
{ {
// setjmp forces volatile registers onto the stack // setjmp forces volatile registers onto the stack
jmp_buf registers REGISTER_BUFFER_ALIGNMENT; jmp_buf registers REGISTER_BUFFER_ALIGNMENT;
...@@ -271,7 +266,15 @@ void MachineThreads::gatherFromCurrentThread(ConservativeRoots& conservativeRoot ...@@ -271,7 +266,15 @@ void MachineThreads::gatherFromCurrentThread(ConservativeRoots& conservativeRoot
#pragma warning(pop) #pragma warning(pop)
#endif #endif
gatherFromCurrentThreadInternal(conservativeRoots); void* registersBegin = &registers;
void* registersEnd = reinterpret_cast<void*>(roundUpToMultipleOf<sizeof(void*)>(reinterpret_cast<uintptr_t>(&registers + 1)));
swapIfBackwards(registersBegin, registersEnd);
conservativeRoots.add(registersBegin, registersEnd);
void* stackBegin = stackCurrent;
void* stackEnd = m_heap->globalData()->stack().origin();
swapIfBackwards(stackBegin, stackEnd);
conservativeRoots.add(stackBegin, stackEnd);
} }
#if ENABLE(JSC_MULTIPLE_THREADS) #if ENABLE(JSC_MULTIPLE_THREADS)
...@@ -456,9 +459,9 @@ void MachineThreads::gatherFromOtherThread(ConservativeRoots& conservativeRoots, ...@@ -456,9 +459,9 @@ void MachineThreads::gatherFromOtherThread(ConservativeRoots& conservativeRoots,
#endif #endif
void MachineThreads::gatherConservativeRoots(ConservativeRoots& conservativeRoots) void MachineThreads::gatherConservativeRoots(ConservativeRoots& conservativeRoots, void* stackCurrent)
{ {
gatherFromCurrentThread(conservativeRoots); gatherFromCurrentThread(conservativeRoots, stackCurrent);
#if ENABLE(JSC_MULTIPLE_THREADS) #if ENABLE(JSC_MULTIPLE_THREADS)
......
...@@ -40,7 +40,7 @@ namespace JSC { ...@@ -40,7 +40,7 @@ namespace JSC {
MachineThreads(Heap*); MachineThreads(Heap*);
~MachineThreads(); ~MachineThreads();
void gatherConservativeRoots(ConservativeRoots&); void gatherConservativeRoots(ConservativeRoots&, void* stackCurrent);
#if ENABLE(JSC_MULTIPLE_THREADS) #if ENABLE(JSC_MULTIPLE_THREADS)
void makeUsableFromMultipleThreads(); void makeUsableFromMultipleThreads();
...@@ -48,8 +48,7 @@ namespace JSC { ...@@ -48,8 +48,7 @@ namespace JSC {
#endif #endif
private: private:
void gatherFromCurrentThread(ConservativeRoots&); void gatherFromCurrentThread(ConservativeRoots&, void* stackCurrent);
void gatherFromCurrentThreadInternal(ConservativeRoots&);
#if ENABLE(JSC_MULTIPLE_THREADS) #if ENABLE(JSC_MULTIPLE_THREADS)
class Thread; class Thread;
......
...@@ -26,9 +26,12 @@ ...@@ -26,9 +26,12 @@
#include "config.h" #include "config.h"
#include "MarkStack.h" #include "MarkStack.h"
#include "ConservativeSet.h"
#include "Heap.h" #include "Heap.h"
#include "JSArray.h" #include "JSArray.h"
#include "JSCell.h" #include "JSCell.h"
#include "JSObject.h"
#include "ScopeChain.h"
#include "Structure.h" #include "Structure.h"
namespace JSC { namespace JSC {
...@@ -42,6 +45,14 @@ void MarkStack::compact() ...@@ -42,6 +45,14 @@ void MarkStack::compact()
m_markSets.shrinkAllocation(s_pageSize); m_markSets.shrinkAllocation(s_pageSize);
} }
void MarkStack::append(ConservativeRoots& conservativeRoots)
{
JSCell** roots = conservativeRoots.roots();
size_t size = conservativeRoots.size();
for (size_t i = 0; i < size; ++i)
internalAppend(roots[i]);
}
inline void MarkStack::markChildren(JSCell* cell) inline void MarkStack::markChildren(JSCell* cell)
{ {
ASSERT(Heap::isMarked(cell)); ASSERT(Heap::isMarked(cell));
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#ifndef MarkStack_h #ifndef MarkStack_h
#define MarkStack_h #define MarkStack_h
#include "ConservativeSet.h"
#include "JSValue.h" #include "JSValue.h"
#include "Register.h" #include "Register.h"
#include "WriteBarrier.h" #include "WriteBarrier.h"
...@@ -36,6 +35,7 @@ ...@@ -36,6 +35,7 @@
namespace JSC { namespace JSC {
class ConservativeRoots;
class JSGlobalData; class JSGlobalData;
class Register; class Register;
...@@ -79,13 +79,7 @@ namespace JSC { ...@@ -79,13 +79,7 @@ namespace JSC {
m_markSets.append(MarkSet(values, values + count, properties)); m_markSets.append(MarkSet(values, values + count, properties));
} }
void append(ConservativeRoots& conservativeRoots) void append(ConservativeRoots&);
{
JSCell** roots = conservativeRoots.roots();
size_t size = conservativeRoots.size();
for (size_t i = 0; i < size; ++i)
internalAppend(roots[i]);
}
void drain(); void drain();
void compact(); void compact();
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <wtf/Bitmap.h> #include <wtf/Bitmap.h>
#include <wtf/PageAllocationAligned.h> #include <wtf/PageAllocationAligned.h>
#include <wtf/StdLibExtras.h>
namespace JSC { namespace JSC {
...@@ -35,15 +36,6 @@ namespace JSC { ...@@ -35,15 +36,6 @@ namespace JSC {
static const size_t KB = 1024; static const size_t KB = 1024;
// Efficient implementation that takes advantage of powers of two.
template<size_t divisor> inline size_t roundUpToMultipleOf(size_t x)
{
COMPILE_ASSERT(divisor && !(divisor & (divisor - 1)), divisor_is_a_power_of_two);
size_t remainderMask = divisor - 1;
return (x + remainderMask) & ~remainderMask;
}
class MarkedBlock { class MarkedBlock {
public: public:
static const size_t atomSize = sizeof(double); // Ensures natural alignment for all built-in types. static const size_t atomSize = sizeof(double); // Ensures natural alignment for all built-in types.
...@@ -109,7 +101,7 @@ namespace JSC { ...@@ -109,7 +101,7 @@ namespace JSC {
inline size_t MarkedBlock::firstAtom() inline size_t MarkedBlock::firstAtom()
{ {
return roundUpToMultipleOf<atomSize>(sizeof(MarkedBlock)) / atomSize; return WTF::roundUpToMultipleOf<atomSize>(sizeof(MarkedBlock)) / atomSize;
} }
inline MarkedBlock::Atom* MarkedBlock::atoms() inline MarkedBlock::Atom* MarkedBlock::atoms()
......
...@@ -114,6 +114,15 @@ inline size_t bitCount(unsigned bits) ...@@ -114,6 +114,15 @@ inline size_t bitCount(unsigned bits)
template<typename T, size_t Size> char (&ArrayLengthHelperFunction(T (&)[Size]))[Size]; template<typename T, size_t Size> char (&ArrayLengthHelperFunction(T (&)[Size]))[Size];
#define WTF_ARRAY_LENGTH(array) sizeof(::WTF::ArrayLengthHelperFunction(array)) #define WTF_ARRAY_LENGTH(array) sizeof(::WTF::ArrayLengthHelperFunction(array))
// Efficient implementation that takes advantage of powers of two.
template<size_t divisor> inline size_t roundUpToMultipleOf(size_t x)
{
COMPILE_ASSERT(divisor && !(divisor & (divisor - 1)), divisor_is_a_power_of_two);
size_t remainderMask = divisor - 1;
return (x + remainderMask) & ~remainderMask;
}
} // namespace WTF } // namespace WTF
#endif // WTF_StdLibExtras_h #endif // WTF_StdLibExtras_h
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