Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (183123 => 183124)
--- trunk/Source/_javascript_Core/ChangeLog 2015-04-22 19:33:52 UTC (rev 183123)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-04-22 20:05:06 UTC (rev 183124)
@@ -1,3 +1,63 @@
+2015-04-22 Mark Lam <[email protected]>
+
+ Give the heap object iterators the ability to return early.
+ https://bugs.webkit.org/show_bug.cgi?id=144011
+
+ Reviewed by Michael Saboff.
+
+ JSDollarVMPrototype::isValidCell() uses a heap object iterator to validate
+ candidate cell pointers, and, when in use, is called a lot more often than
+ the normal way those iterators are used. As a result, I see my instrumented
+ VM killed with a SIGXCPU (CPU time limit exceeded). This patch gives the
+ callback functor the ability to tell the iterators to return early when the
+ functor no longer needs to continue iterating. With this, my instrumented
+ VM is useful again for debugging.
+
+ Since heap iteration is not something that we do in a typical fast path,
+ I don't expect this to have any noticeable impact on performance.
+
+ I also renamed ObjectAddressCheckFunctor to CellAddressCheckFunctor since
+ it checks JSCell addresses, not just JSObjects.
+
+ * _javascript_Core.vcxproj/_javascript_Core.vcxproj:
+ * _javascript_Core.vcxproj/_javascript_Core.vcxproj.filters:
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * debugger/Debugger.cpp:
+ * heap/GCLogging.cpp:
+ (JSC::LoggingFunctor::operator()):
+ * heap/Heap.cpp:
+ (JSC::Zombify::visit):
+ (JSC::Zombify::operator()):
+ * heap/HeapStatistics.cpp:
+ (JSC::StorageStatistics::visit):
+ (JSC::StorageStatistics::operator()):
+ * heap/HeapVerifier.cpp:
+ (JSC::GatherLiveObjFunctor::visit):
+ (JSC::GatherLiveObjFunctor::operator()):
+ * heap/MarkedBlock.cpp:
+ (JSC::SetNewlyAllocatedFunctor::operator()):
+ * heap/MarkedBlock.h:
+ (JSC::MarkedBlock::forEachCell):
+ (JSC::MarkedBlock::forEachLiveCell):
+ (JSC::MarkedBlock::forEachDeadCell):
+ * heap/MarkedSpace.h:
+ (JSC::MarkedSpace::forEachLiveCell):
+ (JSC::MarkedSpace::forEachDeadCell):
+ * inspector/agents/InspectorRuntimeAgent.cpp:
+ (Inspector::TypeRecompiler::visit):
+ (Inspector::TypeRecompiler::operator()):
+ * runtime/IterationStatus.h: Added.
+ * runtime/JSGlobalObject.cpp:
+ * runtime/VM.cpp:
+ (JSC::StackPreservingRecompiler::visit):
+ (JSC::StackPreservingRecompiler::operator()):
+ * tools/JSDollarVMPrototype.cpp:
+ (JSC::CellAddressCheckFunctor::CellAddressCheckFunctor):
+ (JSC::CellAddressCheckFunctor::operator()):
+ (JSC::JSDollarVMPrototype::isValidCell):
+ (JSC::ObjectAddressCheckFunctor::ObjectAddressCheckFunctor): Deleted.
+ (JSC::ObjectAddressCheckFunctor::operator()): Deleted.
+
2015-04-22 Yusuke Suzuki <[email protected]>
[[Set]] should be properly executed in JS builtins
Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj (183123 => 183124)
--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj 2015-04-22 19:33:52 UTC (rev 183123)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj 2015-04-22 20:05:06 UTC (rev 183124)
@@ -1525,6 +1525,7 @@
<ClInclude Include="..\runtime\IntendedStructureChain.h" />
<ClInclude Include="..\runtime\InternalFunction.h" />
<ClInclude Include="..\runtime\Intrinsic.h" />
+ <ClInclude Include="..\runtime\IterationStatus.h" />
<ClInclude Include="..\runtime\IteratorOperations.h" />
<ClInclude Include="..\runtime\JSAPIValueWrapper.h" />
<ClInclude Include="..\runtime\JSLexicalEnvironment.h" />
Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters (183123 => 183124)
--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters 2015-04-22 19:33:52 UTC (rev 183123)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters 2015-04-22 20:05:06 UTC (rev 183124)
@@ -2678,6 +2678,9 @@
<ClInclude Include="..\runtime\Intrinsic.h">
<Filter>runtime</Filter>
</ClInclude>
+ <ClInclude Include="..\runtime\IterationStatus.h">
+ <Filter>runtime</Filter>
+ </ClInclude>
<ClInclude Include="..\runtime\IteratorOperations.h">
<Filter>runtime</Filter>
</ClInclude>
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (183123 => 183124)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2015-04-22 19:33:52 UTC (rev 183123)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2015-04-22 20:05:06 UTC (rev 183124)
@@ -1654,12 +1654,13 @@
FE0D4A091ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE0D4A071ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp */; };
FE20CE9D15F04A9500DF3430 /* LLIntCLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE20CE9B15F04A9500DF3430 /* LLIntCLoop.cpp */; };
FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */; settings = {ATTRIBUTES = (Private, ); }; };
- FE4BFF2B1AD476E700088F87 /* FunctionOverrides.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE4BFF291AD476E700088F87 /* FunctionOverrides.cpp */; };
- FE4BFF2C1AD476E700088F87 /* FunctionOverrides.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4BFF2A1AD476E700088F87 /* FunctionOverrides.h */; };
FE384EE51ADDB7AD0055DE2C /* JSDollarVM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE384EE11ADDB7AD0055DE2C /* JSDollarVM.cpp */; };
FE384EE61ADDB7AD0055DE2C /* JSDollarVM.h in Headers */ = {isa = PBXBuildFile; fileRef = FE384EE21ADDB7AD0055DE2C /* JSDollarVM.h */; settings = {ATTRIBUTES = (Private, ); }; };
FE384EE71ADDB7AD0055DE2C /* JSDollarVMPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE384EE31ADDB7AD0055DE2C /* JSDollarVMPrototype.cpp */; };
FE384EE81ADDB7AD0055DE2C /* JSDollarVMPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = FE384EE41ADDB7AD0055DE2C /* JSDollarVMPrototype.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ FE4BFF2B1AD476E700088F87 /* FunctionOverrides.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE4BFF291AD476E700088F87 /* FunctionOverrides.cpp */; };
+ FE4BFF2C1AD476E700088F87 /* FunctionOverrides.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4BFF2A1AD476E700088F87 /* FunctionOverrides.h */; };
+ FE4D55B81AE716CA0052E459 /* IterationStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4D55B71AE716CA0052E459 /* IterationStatus.h */; settings = {ATTRIBUTES = (Private, ); }; };
FE5932A7183C5A2600A1ECCC /* VMEntryScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE5932A5183C5A2600A1ECCC /* VMEntryScope.cpp */; };
FE5932A8183C5A2600A1ECCC /* VMEntryScope.h in Headers */ = {isa = PBXBuildFile; fileRef = FE5932A6183C5A2600A1ECCC /* VMEntryScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
FE7BA60F1A1A7CEC00F1F7B4 /* HeapVerifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE7BA60D1A1A7CEC00F1F7B4 /* HeapVerifier.cpp */; };
@@ -3446,12 +3447,13 @@
FE0D4A081ABA2437002F54BF /* GlobalContextWithFinalizerTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GlobalContextWithFinalizerTest.h; path = API/tests/GlobalContextWithFinalizerTest.h; sourceTree = "<group>"; };
FE20CE9B15F04A9500DF3430 /* LLIntCLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntCLoop.cpp; path = llint/LLIntCLoop.cpp; sourceTree = "<group>"; };
FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntCLoop.h; path = llint/LLIntCLoop.h; sourceTree = "<group>"; };
- FE4BFF291AD476E700088F87 /* FunctionOverrides.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FunctionOverrides.cpp; sourceTree = "<group>"; };
- FE4BFF2A1AD476E700088F87 /* FunctionOverrides.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionOverrides.h; sourceTree = "<group>"; };
FE384EE11ADDB7AD0055DE2C /* JSDollarVM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDollarVM.cpp; sourceTree = "<group>"; };
FE384EE21ADDB7AD0055DE2C /* JSDollarVM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDollarVM.h; sourceTree = "<group>"; };
FE384EE31ADDB7AD0055DE2C /* JSDollarVMPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDollarVMPrototype.cpp; sourceTree = "<group>"; };
FE384EE41ADDB7AD0055DE2C /* JSDollarVMPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDollarVMPrototype.h; sourceTree = "<group>"; };
+ FE4BFF291AD476E700088F87 /* FunctionOverrides.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FunctionOverrides.cpp; sourceTree = "<group>"; };
+ FE4BFF2A1AD476E700088F87 /* FunctionOverrides.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionOverrides.h; sourceTree = "<group>"; };
+ FE4D55B71AE716CA0052E459 /* IterationStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IterationStatus.h; sourceTree = "<group>"; };
FE5932A5183C5A2600A1ECCC /* VMEntryScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMEntryScope.cpp; sourceTree = "<group>"; };
FE5932A6183C5A2600A1ECCC /* VMEntryScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMEntryScope.h; sourceTree = "<group>"; };
FE7BA60D1A1A7CEC00F1F7B4 /* HeapVerifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HeapVerifier.cpp; sourceTree = "<group>"; };
@@ -4451,6 +4453,7 @@
86BF642A148DB2B5004DE36A /* Intrinsic.h */,
70113D491A8DB093003848C4 /* IteratorOperations.cpp */,
70113D4A1A8DB093003848C4 /* IteratorOperations.h */,
+ FE4D55B71AE716CA0052E459 /* IterationStatus.h */,
93ADFCE60CCBD7AC00D30B08 /* JSArray.cpp */,
938772E5038BFE19008635CE /* JSArray.h */,
0F2B66B417B6B5AB00A7AE3F /* JSArrayBuffer.cpp */,
@@ -5588,6 +5591,7 @@
86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */,
0FE050281AA9095600D33B33 /* ScopedArguments.h in Headers */,
52C0611F1AA51E1C00B4ADBA /* RuntimeType.h in Headers */,
+ FE4D55B81AE716CA0052E459 /* IterationStatus.h in Headers */,
C442CB251A6CDB8C005D3D7C /* JSInputs.json in Headers */,
52678F911A04177C006A306D /* ControlFlowProfiler.h in Headers */,
52678F8F1A031009006A306D /* BasicBlockLocation.h in Headers */,
Modified: trunk/Source/_javascript_Core/debugger/Debugger.cpp (183123 => 183124)
--- trunk/Source/_javascript_Core/debugger/Debugger.cpp 2015-04-22 19:33:52 UTC (rev 183123)
+++ trunk/Source/_javascript_Core/debugger/Debugger.cpp 2015-04-22 20:05:06 UTC (rev 183124)
@@ -44,12 +44,14 @@
public:
Recompiler(JSC::Debugger*);
~Recompiler();
- void operator()(JSCell*);
+ IterationStatus operator()(JSCell*);
private:
typedef HashSet<FunctionExecutable*> FunctionExecutableSet;
typedef HashMap<SourceProvider*, ExecState*> SourceProviderMap;
+ void visit(JSCell*);
+
JSC::Debugger* m_debugger;
FunctionExecutableSet m_functionExecutables;
SourceProviderMap m_sourceProviders;
@@ -69,7 +71,7 @@
m_debugger->sourceParsed(iter->value, iter->key, -1, String());
}
-inline void Recompiler::operator()(JSCell* cell)
+inline void Recompiler::visit(JSCell* cell)
{
if (!cell->inherits(JSFunction::info()))
return;
@@ -92,6 +94,12 @@
m_sourceProviders.add(executable->source().provider(), exec);
}
+inline IterationStatus Recompiler::operator()(JSCell* cell)
+{
+ visit(cell);
+ return IterationStatus::Continue;
+}
+
} // namespace
namespace JSC {
Modified: trunk/Source/_javascript_Core/heap/GCLogging.cpp (183123 => 183124)
--- trunk/Source/_javascript_Core/heap/GCLogging.cpp 2015-04-22 19:33:52 UTC (rev 183123)
+++ trunk/Source/_javascript_Core/heap/GCLogging.cpp 2015-04-22 20:05:06 UTC (rev 183124)
@@ -63,10 +63,11 @@
reviveCells();
}
- void operator()(JSCell* cell)
+ IterationStatus operator()(JSCell* cell)
{
m_liveCells.append(cell);
MarkedBlock::blockFor(cell)->clearMarked(cell);
+ return IterationStatus::Continue;
}
void log()
Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (183123 => 183124)
--- trunk/Source/_javascript_Core/heap/Heap.cpp 2015-04-22 19:33:52 UTC (rev 183123)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp 2015-04-22 20:05:06 UTC (rev 183124)
@@ -240,12 +240,17 @@
}
struct MarkObject : public MarkedBlock::VoidFunctor {
- void operator()(JSCell* cell)
+ inline void visit(JSCell* cell)
{
if (cell->isZapped())
return;
Heap::heap(cell)->setMarked(cell);
}
+ IterationStatus operator()(JSCell* cell)
+ {
+ visit(cell);
+ return IterationStatus::Continue;
+ }
};
struct Count : public MarkedBlock::CountFunctor {
@@ -253,13 +258,19 @@
};
struct CountIfGlobalObject : MarkedBlock::CountFunctor {
- void operator()(JSCell* cell) {
+ inline void visit(JSCell* cell)
+ {
if (!cell->isObject())
return;
if (!asObject(cell)->isGlobalObject())
return;
count(1);
}
+ IterationStatus operator()(JSCell* cell)
+ {
+ visit(cell);
+ return IterationStatus::Continue;
+ }
};
class RecordType {
@@ -267,7 +278,7 @@
typedef std::unique_ptr<TypeCountSet> ReturnType;
RecordType();
- void operator()(JSCell*);
+ IterationStatus operator()(JSCell*);
ReturnType returnValue();
private:
@@ -288,9 +299,10 @@
return info->className;
}
-inline void RecordType::operator()(JSCell* cell)
+inline IterationStatus RecordType::operator()(JSCell* cell)
{
m_typeCountSet->add(typeName(cell));
+ return IterationStatus::Continue;
}
inline std::unique_ptr<TypeCountSet> RecordType::returnValue()
@@ -1422,7 +1434,7 @@
class Zombify : public MarkedBlock::VoidFunctor {
public:
- void operator()(JSCell* cell)
+ inline void visit(JSCell* cell)
{
void** current = reinterpret_cast<void**>(cell);
@@ -1435,6 +1447,11 @@
for (; current < limit; current++)
*current = zombifiedBits;
}
+ IterationStatus operator()(JSCell* cell)
+ {
+ visit(cell);
+ return IterationStatus::Continue;
+ }
};
void Heap::zombifyDeadObjects()
Modified: trunk/Source/_javascript_Core/heap/HeapStatistics.cpp (183123 => 183124)
--- trunk/Source/_javascript_Core/heap/HeapStatistics.cpp 2015-04-22 19:33:52 UTC (rev 183123)
+++ trunk/Source/_javascript_Core/heap/HeapStatistics.cpp 2015-04-22 20:05:06 UTC (rev 183124)
@@ -167,7 +167,7 @@
public:
StorageStatistics();
- void operator()(JSCell*);
+ IterationStatus operator()(JSCell*);
size_t objectWithOutOfLineStorageCount();
size_t objectCount();
@@ -176,6 +176,8 @@
size_t storageCapacity();
private:
+ void visit(JSCell*);
+
size_t m_objectWithOutOfLineStorageCount;
size_t m_objectCount;
size_t m_storageSize;
@@ -190,7 +192,7 @@
{
}
-inline void StorageStatistics::operator()(JSCell* cell)
+inline void StorageStatistics::visit(JSCell* cell)
{
if (!cell->isObject())
return;
@@ -209,6 +211,12 @@
m_storageCapacity += object->structure()->totalStorageCapacity() * sizeof(WriteBarrierBase<Unknown>);
}
+inline IterationStatus StorageStatistics::operator()(JSCell* cell)
+{
+ visit(cell);
+ return IterationStatus::Continue;
+}
+
inline size_t StorageStatistics::objectWithOutOfLineStorageCount()
{
return m_objectWithOutOfLineStorageCount;
Modified: trunk/Source/_javascript_Core/heap/HeapVerifier.cpp (183123 => 183124)
--- trunk/Source/_javascript_Core/heap/HeapVerifier.cpp 2015-04-22 19:33:52 UTC (rev 183123)
+++ trunk/Source/_javascript_Core/heap/HeapVerifier.cpp 2015-04-22 20:05:06 UTC (rev 183124)
@@ -122,7 +122,7 @@
ASSERT(!list.liveObjects.size());
}
- void operator()(JSCell* cell)
+ inline void visit(JSCell* cell)
{
if (!cell->isObject())
return;
@@ -130,6 +130,12 @@
m_list.liveObjects.append(data);
}
+ IterationStatus operator()(JSCell* cell)
+ {
+ visit(cell);
+ return IterationStatus::Continue;
+ }
+
LiveObjectList& m_list;
};
Modified: trunk/Source/_javascript_Core/heap/MarkedBlock.cpp (183123 => 183124)
--- trunk/Source/_javascript_Core/heap/MarkedBlock.cpp 2015-04-22 19:33:52 UTC (rev 183123)
+++ trunk/Source/_javascript_Core/heap/MarkedBlock.cpp 2015-04-22 20:05:06 UTC (rev 183124)
@@ -157,10 +157,11 @@
{
}
- void operator()(JSCell* cell)
+ IterationStatus operator()(JSCell* cell)
{
ASSERT(MarkedBlock::blockFor(cell) == m_block);
m_block->setNewlyAllocated(cell);
+ return IterationStatus::Continue;
}
private:
Modified: trunk/Source/_javascript_Core/heap/MarkedBlock.h (183123 => 183124)
--- trunk/Source/_javascript_Core/heap/MarkedBlock.h 2015-04-22 19:33:52 UTC (rev 183123)
+++ trunk/Source/_javascript_Core/heap/MarkedBlock.h 2015-04-22 20:05:06 UTC (rev 183124)
@@ -25,6 +25,7 @@
#include "HeapBlock.h"
#include "HeapOperation.h"
+#include "IterationStatus.h"
#include "WeakSet.h"
#include <wtf/Bitmap.h>
#include <wtf/DataLog.h>
@@ -179,9 +180,9 @@
void didRetireBlock(const FreeList&);
void willRemoveBlock();
- template <typename Functor> void forEachCell(Functor&);
- template <typename Functor> void forEachLiveCell(Functor&);
- template <typename Functor> void forEachDeadCell(Functor&);
+ template <typename Functor> IterationStatus forEachCell(Functor&);
+ template <typename Functor> IterationStatus forEachLiveCell(Functor&);
+ template <typename Functor> IterationStatus forEachDeadCell(Functor&);
static ptrdiff_t offsetOfMarks() { return OBJECT_OFFSETOF(MarkedBlock, m_marks); }
@@ -444,34 +445,40 @@
return isLive(static_cast<const JSCell*>(p));
}
- template <typename Functor> inline void MarkedBlock::forEachCell(Functor& functor)
+ template <typename Functor> inline IterationStatus MarkedBlock::forEachCell(Functor& functor)
{
for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) {
JSCell* cell = reinterpret_cast_ptr<JSCell*>(&atoms()[i]);
- functor(cell);
+ if (functor(cell) == IterationStatus::Done)
+ return IterationStatus::Done;
}
+ return IterationStatus::Continue;
}
- template <typename Functor> inline void MarkedBlock::forEachLiveCell(Functor& functor)
+ template <typename Functor> inline IterationStatus MarkedBlock::forEachLiveCell(Functor& functor)
{
for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) {
JSCell* cell = reinterpret_cast_ptr<JSCell*>(&atoms()[i]);
if (!isLive(cell))
continue;
- functor(cell);
+ if (functor(cell) == IterationStatus::Done)
+ return IterationStatus::Done;
}
+ return IterationStatus::Continue;
}
- template <typename Functor> inline void MarkedBlock::forEachDeadCell(Functor& functor)
+ template <typename Functor> inline IterationStatus MarkedBlock::forEachDeadCell(Functor& functor)
{
for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) {
JSCell* cell = reinterpret_cast_ptr<JSCell*>(&atoms()[i]);
if (isLive(cell))
continue;
- functor(cell);
+ if (functor(cell) == IterationStatus::Done)
+ return IterationStatus::Done;
}
+ return IterationStatus::Continue;
}
inline bool MarkedBlock::needsSweeping()
Modified: trunk/Source/_javascript_Core/heap/MarkedSpace.h (183123 => 183124)
--- trunk/Source/_javascript_Core/heap/MarkedSpace.h 2015-04-22 19:33:52 UTC (rev 183123)
+++ trunk/Source/_javascript_Core/heap/MarkedSpace.h 2015-04-22 20:05:06 UTC (rev 183124)
@@ -179,8 +179,10 @@
{
ASSERT(isIterating());
BlockIterator end = m_blocks.set().end();
- for (BlockIterator it = m_blocks.set().begin(); it != end; ++it)
- (*it)->forEachLiveCell(functor);
+ for (BlockIterator it = m_blocks.set().begin(); it != end; ++it) {
+ if ((*it)->forEachLiveCell(functor) == IterationStatus::Done)
+ break;
+ }
return functor.returnValue();
}
@@ -194,8 +196,10 @@
{
ASSERT(isIterating());
BlockIterator end = m_blocks.set().end();
- for (BlockIterator it = m_blocks.set().begin(); it != end; ++it)
- (*it)->forEachDeadCell(functor);
+ for (BlockIterator it = m_blocks.set().begin(); it != end; ++it) {
+ if ((*it)->forEachDeadCell(functor) == IterationStatus::Done)
+ break;
+ }
return functor.returnValue();
}
Modified: trunk/Source/_javascript_Core/inspector/agents/InspectorRuntimeAgent.cpp (183123 => 183124)
--- trunk/Source/_javascript_Core/inspector/agents/InspectorRuntimeAgent.cpp 2015-04-22 19:33:52 UTC (rev 183123)
+++ trunk/Source/_javascript_Core/inspector/agents/InspectorRuntimeAgent.cpp 2015-04-22 20:05:06 UTC (rev 183124)
@@ -309,7 +309,7 @@
class TypeRecompiler : public MarkedBlock::VoidFunctor {
public:
- inline void operator()(JSCell* cell)
+ inline void visit(JSCell* cell)
{
if (!cell->inherits(FunctionExecutable::info()))
return;
@@ -318,6 +318,11 @@
executable->clearCodeIfNotCompiling();
executable->clearUnlinkedCodeForRecompilationIfNotCompiling();
}
+ inline IterationStatus operator()(JSCell* cell)
+ {
+ visit(cell);
+ return IterationStatus::Continue;
+ }
};
static void recompileAllJSFunctionsForTypeProfiling(VM& vm, bool shouldEnableTypeProfiling)
Added: trunk/Source/_javascript_Core/runtime/IterationStatus.h (0 => 183124)
--- trunk/Source/_javascript_Core/runtime/IterationStatus.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/IterationStatus.h 2015-04-22 20:05:06 UTC (rev 183124)
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 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. ``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
+ * 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 IterationStatus_h
+#define IterationStatus_h
+
+namespace JSC {
+
+enum class IterationStatus {
+ Continue,
+ Done
+};
+
+} // namespace JSC
+
+#endif // IterationStatus_h
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (183123 => 183124)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2015-04-22 19:33:52 UTC (rev 183123)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2015-04-22 20:05:06 UTC (rev 183124)
@@ -539,9 +539,11 @@
class ObjectsWithBrokenIndexingFinder : public MarkedBlock::VoidFunctor {
public:
ObjectsWithBrokenIndexingFinder(MarkedArgumentBuffer&, JSGlobalObject*);
- void operator()(JSCell*);
+ IterationStatus operator()(JSCell*);
private:
+ void visit(JSCell*);
+
MarkedArgumentBuffer& m_foundObjects;
JSGlobalObject* m_globalObject;
};
@@ -562,7 +564,7 @@
return hasUndecided(type) || hasInt32(type) || hasDouble(type) || hasContiguous(type) || hasArrayStorage(type);
}
-void ObjectsWithBrokenIndexingFinder::operator()(JSCell* cell)
+inline void ObjectsWithBrokenIndexingFinder::visit(JSCell* cell)
{
if (!cell->isObject())
return;
@@ -594,6 +596,12 @@
m_foundObjects.append(object);
}
+IterationStatus ObjectsWithBrokenIndexingFinder::operator()(JSCell* cell)
+{
+ visit(cell);
+ return IterationStatus::Continue;
+}
+
} // end private namespace for helpers for JSGlobalObject::haveABadTime()
void JSGlobalObject::haveABadTime(VM& vm)
Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (183123 => 183124)
--- trunk/Source/_javascript_Core/runtime/VM.cpp 2015-04-22 19:33:52 UTC (rev 183123)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp 2015-04-22 20:05:06 UTC (rev 183124)
@@ -491,7 +491,7 @@
struct StackPreservingRecompiler : public MarkedBlock::VoidFunctor {
HashSet<FunctionExecutable*> currentlyExecutingFunctions;
- void operator()(JSCell* cell)
+ inline void visit(JSCell* cell)
{
if (!cell->inherits(FunctionExecutable::info()))
return;
@@ -500,6 +500,11 @@
return;
executable->clearCodeIfNotCompiling();
}
+ IterationStatus operator()(JSCell* cell)
+ {
+ visit(cell);
+ return IterationStatus::Continue;
+ }
};
void VM::releaseExecutableMemory()
Modified: trunk/Source/_javascript_Core/tools/JSDollarVMPrototype.cpp (183123 => 183124)
--- trunk/Source/_javascript_Core/tools/JSDollarVMPrototype.cpp 2015-04-22 19:33:52 UTC (rev 183123)
+++ trunk/Source/_javascript_Core/tools/JSDollarVMPrototype.cpp 2015-04-22 20:05:06 UTC (rev 183124)
@@ -152,16 +152,19 @@
return heap->storageSpace().contains(candidate);
}
-struct ObjectAddressCheckFunctor : MarkedBlock::CountFunctor {
- ObjectAddressCheckFunctor(JSCell* candidate)
+struct CellAddressCheckFunctor : MarkedBlock::CountFunctor {
+ CellAddressCheckFunctor(JSCell* candidate)
: candidate(candidate)
{
}
- void operator()(JSCell* cell)
+ IterationStatus operator()(JSCell* cell)
{
- if (cell == candidate)
+ if (cell == candidate) {
found = true;
+ return IterationStatus::Done;
+ }
+ return IterationStatus::Continue;
}
JSCell* candidate;
@@ -171,7 +174,7 @@
bool JSDollarVMPrototype::isValidCell(Heap* heap, JSCell* candidate)
{
HeapIterationScope iterationScope(*heap);
- ObjectAddressCheckFunctor functor(candidate);
+ CellAddressCheckFunctor functor(candidate);
heap->objectSpace().forEachLiveCell(iterationScope, functor);
return functor.found;
}