Title: [183124] trunk/Source/_javascript_Core
Revision
183124
Author
[email protected]
Date
2015-04-22 13:05:06 -0700 (Wed, 22 Apr 2015)

Log Message

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.

Modified Paths

Added Paths

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;
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to