]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - heap/ConservativeRoots.cpp
JavaScriptCore-7600.1.4.15.12.tar.gz
[apple/javascriptcore.git] / heap / ConservativeRoots.cpp
index 1aad7797cdc731af285c2c0d448219eed05c1e08..f00b2fbc7e7c73d3c225f6e76e887841cee576b8 100644 (file)
 #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<typename MarkHook>
+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<Bits>(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<JSCell*>(p);
+}
+
+template<typename MarkHook>
+void ConservativeRoots::genericAddSpan(void* begin, void* end, MarkHook& markHook)
 {
-    ASSERT(begin <= end);
-    ASSERT((static_cast<char*>(end) - static_cast<char*>(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<char**>(begin); it != static_cast<char**>(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<typename T, typename U>
+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<JITStubRoutineSet, CodeBlockSet> markHook(jitStubRoutines, codeBlocks);
+    genericAddSpan(begin, end, markHook);
 }
 
 } // namespace JSC