X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/14957cd040308e3eeec43d26bae5d76da13fcd85..40a37d088818fc2fbeba2ef850dbcaaf294befbf:/heap/ConservativeRoots.cpp?ds=sidebyside diff --git a/heap/ConservativeRoots.cpp b/heap/ConservativeRoots.cpp index 1aad779..f00b2fb 100644 --- a/heap/ConservativeRoots.cpp +++ b/heap/ConservativeRoots.cpp @@ -26,11 +26,30 @@ #include "config.h" #include "ConservativeRoots.h" +#include "CodeBlock.h" +#include "CodeBlockSet.h" +#include "CopiedSpace.h" +#include "CopiedSpaceInlines.h" +#include "JSCell.h" +#include "JSObject.h" +#include "JSCInlines.h" +#include "Structure.h" + namespace JSC { -inline bool isPointerAligned(void* p) +ConservativeRoots::ConservativeRoots(const MarkedBlockSet* blocks, CopiedSpace* copiedSpace) + : m_roots(m_inlineRoots) + , m_size(0) + , m_capacity(inlineCapacity) + , m_blocks(blocks) + , m_copiedSpace(copiedSpace) +{ +} + +ConservativeRoots::~ConservativeRoots() { - return !((intptr_t)(p) & (sizeof(char*) - 1)); + if (m_roots != m_inlineRoots) + OSAllocator::decommitAndRelease(m_roots, m_capacity * sizeof(JSCell*)); } void ConservativeRoots::grow() @@ -44,15 +63,92 @@ void ConservativeRoots::grow() m_roots = newRoots; } -void ConservativeRoots::add(void* begin, void* end) +template +inline void ConservativeRoots::genericAddPointer(void* p, TinyBloomFilter filter, MarkHook& markHook) +{ + markHook.mark(p); + + m_copiedSpace->pinIfNecessary(p); + + MarkedBlock* candidate = MarkedBlock::blockFor(p); + if (filter.ruleOut(reinterpret_cast(candidate))) { + ASSERT(!candidate || !m_blocks->set().contains(candidate)); + return; + } + + if (!MarkedBlock::isAtomAligned(p)) + return; + + if (!m_blocks->set().contains(candidate)) + return; + + if (!candidate->isLiveCell(p)) + return; + + if (m_size == m_capacity) + grow(); + + m_roots[m_size++] = static_cast(p); +} + +template +void ConservativeRoots::genericAddSpan(void* begin, void* end, MarkHook& markHook) { - ASSERT(begin <= end); - ASSERT((static_cast(end) - static_cast(begin)) < 0x1000000); - ASSERT(isPointerAligned(begin)); - ASSERT(isPointerAligned(end)); + if (begin > end) { + void* swapTemp = begin; + begin = end; + end = swapTemp; + } + + RELEASE_ASSERT(isPointerAligned(begin)); + RELEASE_ASSERT(isPointerAligned(end)); + TinyBloomFilter filter = m_blocks->filter(); // Make a local copy of filter to show the compiler it won't alias, and can be register-allocated. for (char** it = static_cast(begin); it != static_cast(end); ++it) - add(*it); + genericAddPointer(*it, filter, markHook); +} + +class DummyMarkHook { +public: + void mark(void*) { } +}; + +void ConservativeRoots::add(void* begin, void* end) +{ + DummyMarkHook dummy; + genericAddSpan(begin, end, dummy); +} + +void ConservativeRoots::add(void* begin, void* end, JITStubRoutineSet& jitStubRoutines) +{ + genericAddSpan(begin, end, jitStubRoutines); +} + +template +class CompositeMarkHook { +public: + CompositeMarkHook(T& first, U& second) + : m_first(first) + , m_second(second) + { + } + + void mark(void* address) + { + m_first.mark(address); + m_second.mark(address); + } + +private: + T& m_first; + U& m_second; +}; + +void ConservativeRoots::add( + void* begin, void* end, JITStubRoutineSet& jitStubRoutines, CodeBlockSet& codeBlocks) +{ + CompositeMarkHook markHook(jitStubRoutines, codeBlocks); + genericAddSpan(begin, end, markHook); } } // namespace JSC