Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (88503 => 88504)
--- trunk/Source/_javascript_Core/ChangeLog 2011-06-09 23:46:54 UTC (rev 88503)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-06-10 00:02:23 UTC (rev 88504)
@@ -1,3 +1,63 @@
+2011-06-09 Geoffrey Garen <[email protected]>
+
+ Reviewed by Oliver Hunt.
+
+ Factored MarkedBlock set management into a helper class with a fast case Bloom filter
+ https://bugs.webkit.org/show_bug.cgi?id=62413
+
+ SunSpider reports a small speedup.
+
+ This is in preparation for having ConservativeSet operate on arbitrary
+ sets of MarkedBlocks, and in preparation for conservative scanning
+ becoming proportionally more important than other GC activities.
+
+ * GNUmakefile.list.am:
+ * _javascript_Core.gypi:
+ * _javascript_Core.xcodeproj/project.pbxproj: Build-o.
+
+ * heap/ConservativeRoots.cpp:
+ (JSC::ConservativeRoots::add):
+ * heap/ConservativeRoots.h:
+ (JSC::ConservativeRoots::ConservativeRoots): Operate on a MarkedBlockSet
+ directly, instead of a Heap, so we can operate on subsets of the Heap
+ instead.
+
+ Use a TinyBloomFilter for single-cycle exclusion of most pointers. This
+ is particularly important since we expect not to find our subject pointer
+ in the MarkedBlock hash, and hash misses are more expensive than typical
+ hash lookups because they have high collision rates.
+
+ No need for single-pointer add() to be public anymore, since nobody uses it.
+
+ * heap/Heap.cpp:
+ (JSC::Heap::markRoots):
+ * heap/Heap.h:
+ (JSC::Heap::forEachCell):
+ (JSC::Heap::forEachBlock): Use MarkedBlockSet since that's what
+ ConservativeRoots relies on.
+
+ Nixed contains(), since nobody uses it anymore.
+
+ * heap/MarkedBlock.h:
+ (WTF::MarkedBlockHash::hash): Added a faster hash taking advantage of
+ the VM layout properties of MarkedBlocks.
+
+ * heap/MarkedBlockSet.h: Added.
+ (JSC::MarkedBlockSet::add):
+ (JSC::MarkedBlockSet::remove):
+ (JSC::MarkedBlockSet::recomputeFilter):
+ (JSC::MarkedBlockSet::filter):
+ (JSC::MarkedBlockSet::set):
+ * heap/TinyBloomFilter.h: Added.
+ (JSC::TinyBloomFilter::TinyBloomFilter):
+ (JSC::TinyBloomFilter::add):
+ (JSC::TinyBloomFilter::ruleOut): New helper class, used above.
+
+ * interpreter/RegisterFile.cpp:
+ (JSC::RegisterFile::gatherConservativeRoots): No need to specifically
+ exclude values by tag -- the tiny bloom filter is already a register-register
+ compare, so adding another "rule out" factor just slows things down.
+
2011-06-09 Gavin Barraclough <[email protected]>
Reviewed by Oliver Hunt.
Modified: trunk/Source/_javascript_Core/GNUmakefile.list.am (88503 => 88504)
--- trunk/Source/_javascript_Core/GNUmakefile.list.am 2011-06-09 23:46:54 UTC (rev 88503)
+++ trunk/Source/_javascript_Core/GNUmakefile.list.am 2011-06-10 00:02:23 UTC (rev 88504)
@@ -117,6 +117,8 @@
Source/_javascript_Core/heap/HeapRootVisitor.h \
Source/_javascript_Core/heap/MarkedBlock.cpp \
Source/_javascript_Core/heap/MarkedBlock.h \
+ Source/_javascript_Core/heap/MarkedBlockSet.h \
+ Source/_javascript_Core/heap/TinyBloomFilter.h \
Source/_javascript_Core/heap/NewSpace.cpp \
Source/_javascript_Core/heap/NewSpace.h \
Source/_javascript_Core/heap/Strong.h \
Modified: trunk/Source/_javascript_Core/_javascript_Core.gypi (88503 => 88504)
--- trunk/Source/_javascript_Core/_javascript_Core.gypi 2011-06-09 23:46:54 UTC (rev 88503)
+++ trunk/Source/_javascript_Core/_javascript_Core.gypi 2011-06-10 00:02:23 UTC (rev 88504)
@@ -322,6 +322,8 @@
'heap/HeapRootVisitor.h',
'heap/MarkedBlock.cpp',
'heap/MarkedBlock.h',
+ 'heap/MarkedBlockSet.h',
+ 'heap/TinyBloomFilter.h',
'heap/NewSpace.cpp',
'heap/NewSpace.h',
'debugger/Debugger.cpp',
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (88503 => 88504)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2011-06-09 23:46:54 UTC (rev 88503)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2011-06-10 00:02:23 UTC (rev 88504)
@@ -57,6 +57,8 @@
140D17D70E8AD4A9000CD17D /* JSBasePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 140D17D60E8AD4A9000CD17D /* JSBasePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
141211310A48794D00480255 /* _javascript_Core.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* _javascript_Core.framework */; };
141211340A48795800480255 /* minidom.c in Sources */ = {isa = PBXBuildFile; fileRef = 141211020A48780900480255 /* minidom.c */; };
+ 141448CB13A176EC00F5BA1A /* MarkedBlockSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 141448CA13A176EC00F5BA1A /* MarkedBlockSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 141448CD13A1783700F5BA1A /* TinyBloomFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 141448CC13A1783700F5BA1A /* TinyBloomFilter.h */; settings = {ATTRIBUTES = (Private, ); }; };
1420BE7B10AA6DDB00F455D2 /* WeakRandom.h in Headers */ = {isa = PBXBuildFile; fileRef = 1420BE7A10AA6DDB00F455D2 /* WeakRandom.h */; settings = {ATTRIBUTES = (Private, ); }; };
1421359B0A677F4F00A8195E /* JSBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1421359A0A677F4F00A8195E /* JSBase.cpp */; };
14280823107EC02C0013E7B2 /* Debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8580255597D01FF60F7 /* Debugger.cpp */; };
@@ -726,6 +728,8 @@
141211020A48780900480255 /* minidom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = minidom.c; path = tests/minidom.c; sourceTree = "<group>"; };
1412110D0A48788700480255 /* minidom.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; name = minidom.js; path = tests/minidom.js; sourceTree = "<group>"; };
141211200A48793C00480255 /* minidom */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = minidom; sourceTree = BUILT_PRODUCTS_DIR; };
+ 141448CA13A176EC00F5BA1A /* MarkedBlockSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedBlockSet.h; sourceTree = "<group>"; };
+ 141448CC13A1783700F5BA1A /* TinyBloomFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TinyBloomFilter.h; sourceTree = "<group>"; };
1419D32C0CEA7CDE00FF507A /* RefCounted.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RefCounted.h; sourceTree = "<group>"; };
1420BE7A10AA6DDB00F455D2 /* WeakRandom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakRandom.h; sourceTree = "<group>"; };
1421359A0A677F4F00A8195E /* JSBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSBase.cpp; sourceTree = "<group>"; };
@@ -1505,6 +1509,8 @@
14D2F3D9139F4BE200491031 /* NewSpace.h */,
142E3132134FF0A600AFADB5 /* Strong.h */,
142E3133134FF0A600AFADB5 /* Weak.h */,
+ 141448CA13A176EC00F5BA1A /* MarkedBlockSet.h */,
+ 141448CC13A1783700F5BA1A /* TinyBloomFilter.h */,
);
path = heap;
sourceTree = "<group>";
@@ -2551,6 +2557,8 @@
86BB09C1138E381B0056702F /* DFGRepatch.h in Headers */,
A72FFD64139985A800E5365A /* KeywordLookup.h in Headers */,
14D2F3DB139F4BE200491031 /* NewSpace.h in Headers */,
+ 141448CB13A176EC00F5BA1A /* MarkedBlockSet.h in Headers */,
+ 141448CD13A1783700F5BA1A /* TinyBloomFilter.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Modified: trunk/Source/_javascript_Core/heap/ConservativeRoots.cpp (88503 => 88504)
--- trunk/Source/_javascript_Core/heap/ConservativeRoots.cpp 2011-06-09 23:46:54 UTC (rev 88503)
+++ trunk/Source/_javascript_Core/heap/ConservativeRoots.cpp 2011-06-10 00:02:23 UTC (rev 88504)
@@ -44,6 +44,32 @@
m_roots = newRoots;
}
+inline void ConservativeRoots::add(void* p, TinyBloomFilter filter)
+{
+ 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;
+
+ // The conservative set inverts the typical meaning of mark bits: We only
+ // visit marked pointers, and our visit clears the mark bit. This efficiently
+ // sifts out pointers to dead objects and duplicate pointers.
+ if (!candidate->testAndClearMarked(p))
+ return;
+
+ if (m_size == m_capacity)
+ grow();
+
+ m_roots[m_size++] = static_cast<JSCell*>(p);
+}
+
void ConservativeRoots::add(void* begin, void* end)
{
ASSERT(begin <= end);
@@ -51,8 +77,9 @@
ASSERT(isPointerAligned(begin));
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);
+ add(*it, filter);
}
} // namespace JSC
Modified: trunk/Source/_javascript_Core/heap/ConservativeRoots.h (88503 => 88504)
--- trunk/Source/_javascript_Core/heap/ConservativeRoots.h 2011-06-09 23:46:54 UTC (rev 88503)
+++ trunk/Source/_javascript_Core/heap/ConservativeRoots.h 2011-06-10 00:02:23 UTC (rev 88504)
@@ -37,10 +37,9 @@
class ConservativeRoots {
public:
- ConservativeRoots(Heap*);
+ ConservativeRoots(const MarkedBlockSet*);
~ConservativeRoots();
- void add(void*);
void add(void* begin, void* end);
size_t size();
@@ -50,20 +49,21 @@
static const size_t inlineCapacity = 128;
static const size_t nonInlineCapacity = 8192 / sizeof(JSCell*);
+ void add(void*, TinyBloomFilter);
void grow();
- Heap* m_heap;
JSCell** m_roots;
size_t m_size;
size_t m_capacity;
+ const MarkedBlockSet* m_blocks;
JSCell* m_inlineRoots[inlineCapacity];
};
-inline ConservativeRoots::ConservativeRoots(Heap* heap)
- : m_heap(heap)
- , m_roots(m_inlineRoots)
+inline ConservativeRoots::ConservativeRoots(const MarkedBlockSet* blocks)
+ : m_roots(m_inlineRoots)
, m_size(0)
, m_capacity(inlineCapacity)
+ , m_blocks(blocks)
{
}
@@ -73,23 +73,6 @@
OSAllocator::decommitAndRelease(m_roots, m_capacity * sizeof(JSCell*));
}
-inline void ConservativeRoots::add(void* p)
-{
- if (!m_heap->contains(p))
- return;
-
- // The conservative set inverts the typical meaning of mark bits: We only
- // visit marked pointers, and our visit clears the mark bit. This efficiently
- // sifts out pointers to dead objects and duplicate pointers.
- if (!m_heap->testAndClearMarked(p))
- return;
-
- if (m_size == m_capacity)
- grow();
-
- m_roots[m_size++] = static_cast<JSCell*>(p);
-}
-
inline size_t ConservativeRoots::size()
{
return m_size;
Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (88503 => 88504)
--- trunk/Source/_javascript_Core/heap/Heap.cpp 2011-06-09 23:46:54 UTC (rev 88503)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp 2011-06-10 00:02:23 UTC (rev 88504)
@@ -404,19 +404,19 @@
void* dummy;
- MarkStack& visitor = m_markStack;
- HeapRootVisitor heapRootVisitor(visitor);
-
// We gather conservative roots before clearing mark bits because conservative
// gathering uses the mark bits to determine whether a reference is valid.
- ConservativeRoots machineThreadRoots(this);
+ ConservativeRoots machineThreadRoots(&m_blocks);
m_machineThreads.gatherConservativeRoots(machineThreadRoots, &dummy);
- ConservativeRoots registerFileRoots(this);
+ ConservativeRoots registerFileRoots(&m_blocks);
registerFile().gatherConservativeRoots(registerFileRoots);
clearMarks();
+ MarkStack& visitor = m_markStack;
+ HeapRootVisitor heapRootVisitor(visitor);
+
visitor.append(machineThreadRoots);
visitor.drain();
Modified: trunk/Source/_javascript_Core/heap/Heap.h (88503 => 88504)
--- trunk/Source/_javascript_Core/heap/Heap.h 2011-06-09 23:46:54 UTC (rev 88503)
+++ trunk/Source/_javascript_Core/heap/Heap.h 2011-06-10 00:02:23 UTC (rev 88504)
@@ -25,6 +25,7 @@
#include "HandleHeap.h"
#include "HandleStack.h"
#include "MarkStack.h"
+#include "MarkedBlockSet.h"
#include "NewSpace.h"
#include <wtf/Forward.h>
#include <wtf/HashCountedSet.h>
@@ -89,8 +90,6 @@
void protect(JSValue);
bool unprotect(JSValue); // True when the protect count drops to 0.
- bool contains(const void*);
-
size_t size();
size_t capacity();
size_t objectCount();
@@ -145,7 +144,7 @@
OperationInProgress m_operationInProgress;
NewSpace m_newSpace;
- HashSet<MarkedBlock*> m_blocks;
+ MarkedBlockSet m_blocks;
size_t m_extraCost;
@@ -208,18 +207,6 @@
{
}
- inline bool Heap::contains(const void* x)
- {
- if (!MarkedBlock::isAtomAligned(x))
- return false;
-
- MarkedBlock* block = MarkedBlock::blockFor(x);
- if (!block || !m_blocks.contains(block))
- return false;
-
- return true;
- }
-
inline void Heap::reportExtraMemoryCost(size_t cost)
{
if (cost > minExtraCost)
@@ -244,8 +231,8 @@
template<typename Functor> inline typename Functor::ReturnType Heap::forEachCell(Functor& functor)
{
- BlockIterator end = m_blocks.end();
- for (BlockIterator it = m_blocks.begin(); it != end; ++it)
+ BlockIterator end = m_blocks.set().end();
+ for (BlockIterator it = m_blocks.set().begin(); it != end; ++it)
(*it)->forEachCell(functor);
return functor.returnValue();
}
@@ -258,8 +245,8 @@
template<typename Functor> inline typename Functor::ReturnType Heap::forEachBlock(Functor& functor)
{
- BlockIterator end = m_blocks.end();
- for (BlockIterator it = m_blocks.begin(); it != end; ++it)
+ BlockIterator end = m_blocks.set().end();
+ for (BlockIterator it = m_blocks.set().begin(); it != end; ++it)
functor(*it);
return functor.returnValue();
}
Modified: trunk/Source/_javascript_Core/heap/MarkedBlock.h (88503 => 88504)
--- trunk/Source/_javascript_Core/heap/MarkedBlock.h 2011-06-09 23:46:54 UTC (rev 88503)
+++ trunk/Source/_javascript_Core/heap/MarkedBlock.h 2011-06-10 00:02:23 UTC (rev 88504)
@@ -24,6 +24,7 @@
#include <wtf/Bitmap.h>
#include <wtf/DoublyLinkedList.h>
+#include <wtf/HashFunctions.h>
#include <wtf/PageAllocationAligned.h>
#include <wtf/StdLibExtras.h>
@@ -47,6 +48,7 @@
};
static const size_t atomSize = sizeof(double); // Ensures natural alignment for all built-in types.
+ static const size_t blockSize = 16 * KB;
static MarkedBlock* create(Heap*, size_t cellSize);
static void destroy(MarkedBlock*);
@@ -80,7 +82,6 @@
template <typename Functor> void forEachCell(Functor&);
private:
- static const size_t blockSize = 16 * KB;
static const size_t blockMask = ~(blockSize - 1); // blockSize must be a power of two.
static const size_t atomMask = ~(atomSize - 1); // atomSize must be a power of two.
@@ -215,4 +216,22 @@
} // namespace JSC
+namespace WTF {
+
+ struct MarkedBlockHash : PtrHash<JSC::MarkedBlock*> {
+ static unsigned hash(JSC::MarkedBlock* const& key)
+ {
+ // Aligned VM regions tend to be monotonically increasing integers,
+ // which is a great hash function, but we have to remove the low bits,
+ // since they're always zero, which is a terrible hash function!
+ return reinterpret_cast<JSC::Bits>(key) / JSC::MarkedBlock::blockSize;
+ }
+ };
+
+ template<> struct DefaultHash<JSC::MarkedBlock*> {
+ typedef MarkedBlockHash Hash;
+ };
+
+} // namespace WTF
+
#endif // MarkedBlock_h
Added: trunk/Source/_javascript_Core/heap/MarkedBlockSet.h (0 => 88504)
--- trunk/Source/_javascript_Core/heap/MarkedBlockSet.h (rev 0)
+++ trunk/Source/_javascript_Core/heap/MarkedBlockSet.h 2011-06-10 00:02:23 UTC (rev 88504)
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MarkedBlockSet_h
+#define MarkedBlockSet_h
+
+#include "MarkedBlock.h"
+#include "TinyBloomFilter.h"
+
+namespace JSC {
+
+class MarkedBlock;
+
+class MarkedBlockSet {
+public:
+ void add(MarkedBlock*);
+ void remove(MarkedBlock*);
+
+ TinyBloomFilter filter() const;
+ const HashSet<MarkedBlock*>& set() const;
+
+private:
+ void recomputeFilter();
+
+ TinyBloomFilter m_filter;
+ HashSet<MarkedBlock*> m_set;
+};
+
+inline void MarkedBlockSet::add(MarkedBlock* block)
+{
+ m_filter.add(reinterpret_cast<Bits>(block));
+ m_set.add(block);
+}
+
+inline void MarkedBlockSet::remove(MarkedBlock* block)
+{
+ int oldCapacity = m_set.capacity();
+ m_set.remove(block);
+ if (m_set.capacity() != oldCapacity) // Indicates we've removed a lot of blocks.
+ recomputeFilter();
+}
+
+inline void MarkedBlockSet::recomputeFilter()
+{
+ TinyBloomFilter filter;
+ for (HashSet<MarkedBlock*>::iterator it = m_set.begin(); it != m_set.end(); ++it)
+ filter.add(reinterpret_cast<Bits>(*it));
+ m_filter = filter;
+}
+
+inline TinyBloomFilter MarkedBlockSet::filter() const
+{
+ return m_filter;
+}
+
+inline const HashSet<MarkedBlock*>& MarkedBlockSet::set() const
+{
+ return m_set;
+}
+
+} // namespace JSC
+
+#endif // MarkedBlockSet_h
Added: trunk/Source/_javascript_Core/heap/TinyBloomFilter.h (0 => 88504)
--- trunk/Source/_javascript_Core/heap/TinyBloomFilter.h (rev 0)
+++ trunk/Source/_javascript_Core/heap/TinyBloomFilter.h 2011-06-10 00:02:23 UTC (rev 88504)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TinyBloomFilter_h
+#define TinyBloomFilter_h
+
+namespace JSC {
+
+typedef uintptr_t Bits;
+
+class TinyBloomFilter {
+public:
+ TinyBloomFilter();
+
+ void add(Bits);
+ bool ruleOut(Bits) const; // True for 0.
+
+private:
+ Bits m_bits;
+};
+
+inline TinyBloomFilter::TinyBloomFilter()
+ : m_bits(0)
+{
+}
+
+inline void TinyBloomFilter::add(Bits bits)
+{
+ m_bits |= bits;
+}
+
+inline bool TinyBloomFilter::ruleOut(Bits bits) const
+{
+ if (!bits)
+ return true;
+
+ if ((bits & m_bits) != bits)
+ return true;
+
+ return false;
+}
+
+} // namespace JSC
+
+#endif // TinyBloomFilter_h
Modified: trunk/Source/_javascript_Core/interpreter/RegisterFile.cpp (88503 => 88504)
--- trunk/Source/_javascript_Core/interpreter/RegisterFile.cpp 2011-06-09 23:46:54 UTC (rev 88503)
+++ trunk/Source/_javascript_Core/interpreter/RegisterFile.cpp 2011-06-10 00:02:23 UTC (rev 88504)
@@ -54,12 +54,7 @@
void RegisterFile::gatherConservativeRoots(ConservativeRoots& conservativeRoots)
{
- for (Register* it = start(); it != end(); ++it) {
- JSValue v = it->jsValue();
- if (!v.isCell())
- continue;
- conservativeRoots.add(v.asCell());
- }
+ conservativeRoots.add(start(), end());
}
void RegisterFile::releaseExcessCapacity()