REGRESSION(r172129): ftlopt branch merge made performance tests flakey crash
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Aug 2014 00:55:31 +0000 (00:55 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Aug 2014 00:55:31 +0000 (00:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=135750

Reviewed by Mark Lam.

This was caused by a rather embarrassing oversight in how the DFG tracks structures: we
could sometimes perform an optimization that requires a structure to be alive but forget to
ensure that the structure is actually kept alive. In particular, any watchpoint-based
optimizations involve setting watchpoints even if the code that got optimized is eventually
deleted because it is unreachable. All such optimizations would leave behind something in
the IR to tell us that we are interested in the structure and that therefore it should be
kept alive. But, IR can be deleted if it is unreachable.

The solution is to ensure that as soon as the DFG is made aware of a structure, it adds it
to the set of weak references.

* JavaScriptCore.xcodeproj/project.pbxproj:
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGAbstractValue.cpp:
(JSC::DFG::AbstractValue::setOSREntryValue):
(JSC::DFG::AbstractValue::set):
(JSC::DFG::AbstractValue::normalizeClarity):
(JSC::DFG::AbstractValue::assertIsRegistered):
(JSC::DFG::AbstractValue::assertIsWatched): Deleted.
* dfg/DFGAbstractValue.h:
(JSC::DFG::AbstractValue::assertIsRegistered):
(JSC::DFG::AbstractValue::assertIsWatched): Deleted.
* dfg/DFGCommon.h:
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
* dfg/DFGDesiredWeakReferences.cpp:
(JSC::DFG::DesiredWeakReferences::addLazily):
(JSC::DFG::DesiredWeakReferences::contains):
(JSC::DFG::DesiredWeakReferences::reallyAdd):
(JSC::DFG::DesiredWeakReferences::visitChildren):
* dfg/DFGDesiredWeakReferences.h:
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::canOptimizeStringObjectAccess):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::Graph):
(JSC::DFG::Graph::registerFrozenValues):
(JSC::DFG::Graph::convertToConstant):
(JSC::DFG::Graph::registerStructure):
(JSC::DFG::Graph::assertIsRegistered):
(JSC::DFG::Graph::assertIsWatched): Deleted.
* dfg/DFGGraph.h:
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThreadImpl):
* dfg/DFGStructureAbstractValue.cpp:
(JSC::DFG::StructureAbstractValue::assertIsRegistered):
(JSC::DFG::StructureAbstractValue::assertIsWatched): Deleted.
* dfg/DFGStructureAbstractValue.h:
(JSC::DFG::StructureAbstractValue::assertIsRegistered):
(JSC::DFG::StructureAbstractValue::assertIsWatched): Deleted.
* dfg/DFGStructureRegistrationPhase.cpp: Copied from Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.cpp.
(JSC::DFG::StructureRegistrationPhase::StructureRegistrationPhase):
(JSC::DFG::StructureRegistrationPhase::run):
(JSC::DFG::StructureRegistrationPhase::registerStructures):
(JSC::DFG::StructureRegistrationPhase::registerStructure):
(JSC::DFG::performStructureRegistration):
(JSC::DFG::WatchableStructureWatchingPhase::WatchableStructureWatchingPhase): Deleted.
(JSC::DFG::WatchableStructureWatchingPhase::run): Deleted.
(JSC::DFG::WatchableStructureWatchingPhase::tryWatch): Deleted.
(JSC::DFG::performWatchableStructureWatching): Deleted.
* dfg/DFGStructureRegistrationPhase.h: Copied from Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.h.
* dfg/DFGWatchableStructureWatchingPhase.cpp: Removed.
* dfg/DFGWatchableStructureWatchingPhase.h: Removed.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@172737 268f45cc-cd09-0410-ab3c-d52691b4dbfc

17 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
Source/JavaScriptCore/dfg/DFGAbstractValue.cpp
Source/JavaScriptCore/dfg/DFGAbstractValue.h
Source/JavaScriptCore/dfg/DFGCommon.h
Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
Source/JavaScriptCore/dfg/DFGDesiredWeakReferences.cpp
Source/JavaScriptCore/dfg/DFGDesiredWeakReferences.h
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
Source/JavaScriptCore/dfg/DFGGraph.cpp
Source/JavaScriptCore/dfg/DFGGraph.h
Source/JavaScriptCore/dfg/DFGPlan.cpp
Source/JavaScriptCore/dfg/DFGStructureAbstractValue.cpp
Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h
Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp [moved from Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.cpp with 67% similarity]
Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.h [moved from Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.h with 79% similarity]

index 211fe60..858ed45 100644 (file)
@@ -1,3 +1,74 @@
+2014-08-18  Filip Pizlo  <fpizlo@apple.com>
+
+        REGRESSION(r172129): ftlopt branch merge made performance tests flakey crash
+        https://bugs.webkit.org/show_bug.cgi?id=135750
+
+        Reviewed by Mark Lam.
+        
+        This was caused by a rather embarrassing oversight in how the DFG tracks structures: we
+        could sometimes perform an optimization that requires a structure to be alive but forget to
+        ensure that the structure is actually kept alive. In particular, any watchpoint-based
+        optimizations involve setting watchpoints even if the code that got optimized is eventually
+        deleted because it is unreachable. All such optimizations would leave behind something in
+        the IR to tell us that we are interested in the structure and that therefore it should be
+        kept alive. But, IR can be deleted if it is unreachable.
+        
+        The solution is to ensure that as soon as the DFG is made aware of a structure, it adds it
+        to the set of weak references.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGAbstractValue.cpp:
+        (JSC::DFG::AbstractValue::setOSREntryValue):
+        (JSC::DFG::AbstractValue::set):
+        (JSC::DFG::AbstractValue::normalizeClarity):
+        (JSC::DFG::AbstractValue::assertIsRegistered):
+        (JSC::DFG::AbstractValue::assertIsWatched): Deleted.
+        * dfg/DFGAbstractValue.h:
+        (JSC::DFG::AbstractValue::assertIsRegistered):
+        (JSC::DFG::AbstractValue::assertIsWatched): Deleted.
+        * dfg/DFGCommon.h:
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
+        * dfg/DFGDesiredWeakReferences.cpp:
+        (JSC::DFG::DesiredWeakReferences::addLazily):
+        (JSC::DFG::DesiredWeakReferences::contains):
+        (JSC::DFG::DesiredWeakReferences::reallyAdd):
+        (JSC::DFG::DesiredWeakReferences::visitChildren):
+        * dfg/DFGDesiredWeakReferences.h:
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::canOptimizeStringObjectAccess):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::Graph):
+        (JSC::DFG::Graph::registerFrozenValues):
+        (JSC::DFG::Graph::convertToConstant):
+        (JSC::DFG::Graph::registerStructure):
+        (JSC::DFG::Graph::assertIsRegistered):
+        (JSC::DFG::Graph::assertIsWatched): Deleted.
+        * dfg/DFGGraph.h:
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGStructureAbstractValue.cpp:
+        (JSC::DFG::StructureAbstractValue::assertIsRegistered):
+        (JSC::DFG::StructureAbstractValue::assertIsWatched): Deleted.
+        * dfg/DFGStructureAbstractValue.h:
+        (JSC::DFG::StructureAbstractValue::assertIsRegistered):
+        (JSC::DFG::StructureAbstractValue::assertIsWatched): Deleted.
+        * dfg/DFGStructureRegistrationPhase.cpp: Copied from Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.cpp.
+        (JSC::DFG::StructureRegistrationPhase::StructureRegistrationPhase):
+        (JSC::DFG::StructureRegistrationPhase::run):
+        (JSC::DFG::StructureRegistrationPhase::registerStructures):
+        (JSC::DFG::StructureRegistrationPhase::registerStructure):
+        (JSC::DFG::performStructureRegistration):
+        (JSC::DFG::WatchableStructureWatchingPhase::WatchableStructureWatchingPhase): Deleted.
+        (JSC::DFG::WatchableStructureWatchingPhase::run): Deleted.
+        (JSC::DFG::WatchableStructureWatchingPhase::tryWatch): Deleted.
+        (JSC::DFG::performWatchableStructureWatching): Deleted.
+        * dfg/DFGStructureRegistrationPhase.h: Copied from Source/JavaScriptCore/dfg/DFGWatchableStructureWatchingPhase.h.
+        * dfg/DFGWatchableStructureWatchingPhase.cpp: Removed.
+        * dfg/DFGWatchableStructureWatchingPhase.h: Removed.
+
 2014-08-18  Akos Kiss  <akiss@inf.u-szeged.hu>
 
         Fix ASSERT in ARM64's JSC::GPRInfo::debugName
index 2f4c0b8..b33e715 100644 (file)
                0F766D3815AE4A1C008F363E /* StructureStubClearingWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F766D3615AE4A1A008F363E /* StructureStubClearingWatchpoint.cpp */; };
                0F766D3915AE4A1F008F363E /* StructureStubClearingWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F766D3715AE4A1A008F363E /* StructureStubClearingWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F7700921402FF3C0078EB39 /* SamplingCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7700911402FF280078EB39 /* SamplingCounter.cpp */; };
+               0F79085519A290B200F6310C /* DFGStructureRegistrationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F79085319A290B200F6310C /* DFGStructureRegistrationPhase.cpp */; };
+               0F79085619A290B200F6310C /* DFGStructureRegistrationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F79085419A290B200F6310C /* DFGStructureRegistrationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD82E1F14172C2F00179C94 /* DFGCapabilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F7B294D14C3CD4C007C3DB1 /* DFGCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC0977E1469EBC400CF2442 /* DFGCommon.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F7B3661197C525C00ED1DDC /* DFGPhantomCanonicalizationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7B365F197C525C00ED1DDC /* DFGPhantomCanonicalizationPhase.cpp */; };
                0FCEFADF180738C000472CE4 /* FTLLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FCEFADD180738C000472CE4 /* FTLLocation.cpp */; };
                0FCEFAE0180738C000472CE4 /* FTLLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCEFADE180738C000472CE4 /* FTLLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FD2C92416D01EE900C7803F /* StructureInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD2C92316D01EE900C7803F /* StructureInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               0FD2D4FE192FEE5800A178BF /* DFGWatchableStructureWatchingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD2D4FC192FEE5800A178BF /* DFGWatchableStructureWatchingPhase.cpp */; };
-               0FD2D4FF192FEE5800A178BF /* DFGWatchableStructureWatchingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD2D4FD192FEE5800A178BF /* DFGWatchableStructureWatchingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FD3C82614115D4000FD81CB /* DFGDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD3C82014115CF800FD81CB /* DFGDriver.cpp */; };
                0FD3C82814115D4F00FD81CB /* DFGDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD3C82214115D0E00FD81CB /* DFGDriver.h */; };
                0FD81AD2154FB4EE00983E72 /* DFGDominators.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD81ACF154FB4EB00983E72 /* DFGDominators.cpp */; };
                0F766D3715AE4A1A008F363E /* StructureStubClearingWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureStubClearingWatchpoint.h; sourceTree = "<group>"; };
                0F77008E1402FDD60078EB39 /* SamplingCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SamplingCounter.h; sourceTree = "<group>"; };
                0F7700911402FF280078EB39 /* SamplingCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SamplingCounter.cpp; sourceTree = "<group>"; };
+               0F79085319A290B200F6310C /* DFGStructureRegistrationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStructureRegistrationPhase.cpp; path = dfg/DFGStructureRegistrationPhase.cpp; sourceTree = "<group>"; };
+               0F79085419A290B200F6310C /* DFGStructureRegistrationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureRegistrationPhase.h; path = dfg/DFGStructureRegistrationPhase.h; sourceTree = "<group>"; };
                0F7B365F197C525C00ED1DDC /* DFGPhantomCanonicalizationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPhantomCanonicalizationPhase.cpp; path = dfg/DFGPhantomCanonicalizationPhase.cpp; sourceTree = "<group>"; };
                0F7B3660197C525C00ED1DDC /* DFGPhantomCanonicalizationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPhantomCanonicalizationPhase.h; path = dfg/DFGPhantomCanonicalizationPhase.h; sourceTree = "<group>"; };
                0F8023E91613832300A0BA45 /* ByValInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ByValInfo.h; sourceTree = "<group>"; };
                0FCEFADD180738C000472CE4 /* FTLLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLLocation.cpp; path = ftl/FTLLocation.cpp; sourceTree = "<group>"; };
                0FCEFADE180738C000472CE4 /* FTLLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLLocation.h; path = ftl/FTLLocation.h; sourceTree = "<group>"; };
                0FD2C92316D01EE900C7803F /* StructureInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureInlines.h; sourceTree = "<group>"; };
-               0FD2D4FC192FEE5800A178BF /* DFGWatchableStructureWatchingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGWatchableStructureWatchingPhase.cpp; path = dfg/DFGWatchableStructureWatchingPhase.cpp; sourceTree = "<group>"; };
-               0FD2D4FD192FEE5800A178BF /* DFGWatchableStructureWatchingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGWatchableStructureWatchingPhase.h; path = dfg/DFGWatchableStructureWatchingPhase.h; sourceTree = "<group>"; };
                0FD3C82014115CF800FD81CB /* DFGDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDriver.cpp; path = dfg/DFGDriver.cpp; sourceTree = "<group>"; };
                0FD3C82214115D0E00FD81CB /* DFGDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDriver.h; path = dfg/DFGDriver.h; sourceTree = "<group>"; };
                0FD5652216AB780A00197653 /* DFGBasicBlockInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBasicBlockInlines.h; path = dfg/DFGBasicBlockInlines.h; sourceTree = "<group>"; };
                C2FCAE0F17A9C24E0034C735 /* BytecodeLivenessAnalysis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeLivenessAnalysis.h; sourceTree = "<group>"; };
                C2FE18A316BAEC4000AF3061 /* StructureRareData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureRareData.h; sourceTree = "<group>"; };
                C4703CBF192844960013FBEA /* generate-inspector-protocol-bindings.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = "generate-inspector-protocol-bindings.py"; sourceTree = "<group>"; };
-               C4703CC2192844CC0013FBEA /* __init__.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; name = __init__.py; path = __init__.py; sourceTree = "<group>"; };
-               C4703CC3192844CC0013FBEA /* generate_backend_commands.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; name = generate_backend_commands.py; path = generate_backend_commands.py; sourceTree = "<group>"; };
-               C4703CC4192844CC0013FBEA /* generate_backend_dispatcher_header.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; name = generate_backend_dispatcher_header.py; path = generate_backend_dispatcher_header.py; sourceTree = "<group>"; };
-               C4703CC5192844CC0013FBEA /* generate_backend_dispatcher_implementation.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; name = generate_backend_dispatcher_implementation.py; path = generate_backend_dispatcher_implementation.py; sourceTree = "<group>"; };
-               C4703CC6192844CC0013FBEA /* generate_frontend_dispatcher_header.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; name = generate_frontend_dispatcher_header.py; path = generate_frontend_dispatcher_header.py; sourceTree = "<group>"; };
-               C4703CC7192844CC0013FBEA /* generate_frontend_dispatcher_implementation.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; name = generate_frontend_dispatcher_implementation.py; path = generate_frontend_dispatcher_implementation.py; sourceTree = "<group>"; };
-               C4703CC8192844CC0013FBEA /* generate_type_builder_header.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; name = generate_type_builder_header.py; path = generate_type_builder_header.py; sourceTree = "<group>"; };
-               C4703CC9192844CC0013FBEA /* generate_type_builder_implementation.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; name = generate_type_builder_implementation.py; path = generate_type_builder_implementation.py; sourceTree = "<group>"; };
-               C4703CCA192844CC0013FBEA /* generator_templates.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; name = generator_templates.py; path = generator_templates.py; sourceTree = "<group>"; };
-               C4703CCB192844CC0013FBEA /* generator.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; name = generator.py; path = generator.py; sourceTree = "<group>"; };
-               C4703CCC192844CC0013FBEA /* models.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; name = models.py; path = models.py; sourceTree = "<group>"; };
+               C4703CC2192844CC0013FBEA /* __init__.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = __init__.py; sourceTree = "<group>"; };
+               C4703CC3192844CC0013FBEA /* generate_backend_commands.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_backend_commands.py; sourceTree = "<group>"; };
+               C4703CC4192844CC0013FBEA /* generate_backend_dispatcher_header.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_backend_dispatcher_header.py; sourceTree = "<group>"; };
+               C4703CC5192844CC0013FBEA /* generate_backend_dispatcher_implementation.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_backend_dispatcher_implementation.py; sourceTree = "<group>"; };
+               C4703CC6192844CC0013FBEA /* generate_frontend_dispatcher_header.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_frontend_dispatcher_header.py; sourceTree = "<group>"; };
+               C4703CC7192844CC0013FBEA /* generate_frontend_dispatcher_implementation.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_frontend_dispatcher_implementation.py; sourceTree = "<group>"; };
+               C4703CC8192844CC0013FBEA /* generate_type_builder_header.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_type_builder_header.py; sourceTree = "<group>"; };
+               C4703CC9192844CC0013FBEA /* generate_type_builder_implementation.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generate_type_builder_implementation.py; sourceTree = "<group>"; };
+               C4703CCA192844CC0013FBEA /* generator_templates.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generator_templates.py; sourceTree = "<group>"; };
+               C4703CCB192844CC0013FBEA /* generator.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = generator.py; sourceTree = "<group>"; };
+               C4703CCC192844CC0013FBEA /* models.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = models.py; sourceTree = "<group>"; };
                D21202280AD4310C00ED79B6 /* DateConversion.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DateConversion.cpp; sourceTree = "<group>"; };
                D21202290AD4310C00ED79B6 /* DateConversion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DateConversion.h; sourceTree = "<group>"; };
                E124A8F50E555775003091F1 /* OpaqueJSString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpaqueJSString.h; sourceTree = "<group>"; };
                                0F893BDA1936E23C001211F4 /* DFGStructureAbstractValue.cpp */,
                                0F63947615DCE347006A597C /* DFGStructureAbstractValue.h */,
                                0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */,
+                               0F79085319A290B200F6310C /* DFGStructureRegistrationPhase.cpp */,
+                               0F79085419A290B200F6310C /* DFGStructureRegistrationPhase.h */,
                                0F2FCCF718A60070001A27F8 /* DFGThreadData.cpp */,
                                0F2FCCF818A60070001A27F8 /* DFGThreadData.h */,
                                0FC0979F146B28C700CF2442 /* DFGThunks.cpp */,
                                0F2BDC431522801700CD8910 /* DFGVariableEventStream.h */,
                                0FFFC95314EF909500C72532 /* DFGVirtualRegisterAllocationPhase.cpp */,
                                0FFFC95414EF909500C72532 /* DFGVirtualRegisterAllocationPhase.h */,
-                               0FD2D4FC192FEE5800A178BF /* DFGWatchableStructureWatchingPhase.cpp */,
-                               0FD2D4FD192FEE5800A178BF /* DFGWatchableStructureWatchingPhase.h */,
                                0FC97F3B18202119002C9B26 /* DFGWatchpointCollectionPhase.cpp */,
                                0FC97F3C18202119002C9B26 /* DFGWatchpointCollectionPhase.h */,
                                0FDB2CE5174830A2007B3C1B /* DFGWorklist.cpp */,
                                0F2FCCFA18A60070001A27F8 /* DFGGraphSafepoint.h in Headers */,
                                0FB14E211812570B009B6B4D /* DFGInlineCacheWrapper.h in Headers */,
                                0FB14E2318130955009B6B4D /* DFGInlineCacheWrapperInlines.h in Headers */,
+                               0F79085619A290B200F6310C /* DFGStructureRegistrationPhase.h in Headers */,
                                A704D90617A0BAA8006BA554 /* DFGInPlaceAbstractState.h in Headers */,
                                0F2BDC21151E803B00CD8910 /* DFGInsertionSet.h in Headers */,
                                0F300B7C18AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.h in Headers */,
                                0F485328187DFDEC0083B687 /* FTLAvailableRecovery.h in Headers */,
                                0FEA0A0A170513DB00BB722C /* FTLCapabilities.h in Headers */,
                                0FEA0A231709606900BB722C /* FTLCommonValues.h in Headers */,
-                               0FD2D4FF192FEE5800A178BF /* DFGWatchableStructureWatchingPhase.h in Headers */,
                                0FEA0A0C170513DB00BB722C /* FTLCompile.h in Headers */,
                                0FE95F7A18B5694700B531FB /* FTLDataSection.h in Headers */,
                                2AC922BC18A16182003CE0FB /* FTLDWARFDebugLineInfo.h in Headers */,
                                0FF0F19916B729F6005DF95B /* DFGLongLivedState.cpp in Sources */,
                                A767B5B517A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.cpp in Sources */,
                                0F2BDC4D1522818600CD8910 /* DFGMinifiedNode.cpp in Sources */,
-                               0FD2D4FE192FEE5800A178BF /* DFGWatchableStructureWatchingPhase.cpp in Sources */,
                                A737810D1799EA2E00817533 /* DFGNaturalLoops.cpp in Sources */,
                                0FF0F19C16B72A03005DF95B /* DFGNode.cpp in Sources */,
                                0FA581BA150E952C00B9A2D9 /* DFGNodeFlags.cpp in Sources */,
                                0F0332C018ADFAE1005F979A /* ExitingJITType.cpp in Sources */,
                                0FB105851675480F00F8AB6E /* ExitKind.cpp in Sources */,
                                0FEA0A1C1708B00700BB722C /* FTLAbstractHeap.cpp in Sources */,
+                               0F79085519A290B200F6310C /* DFGStructureRegistrationPhase.cpp in Sources */,
                                0FEA0A1E1708B00700BB722C /* FTLAbstractHeapRepository.cpp in Sources */,
                                0F485327187DFDEC0083B687 /* FTLAvailableRecovery.cpp in Sources */,
                                0FEA0A09170513DB00BB722C /* FTLCapabilities.cpp in Sources */,
index db89748..25de4d8 100644 (file)
@@ -1773,7 +1773,7 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
                         transitions.append(
                             Transition(
                                 variant.oldStructureForTransition(), variant.newStructure()));
-                        m_graph.watchpoints().consider(variant.newStructure());
+                        m_graph.registerStructure(variant.newStructure());
                         newSet.add(variant.newStructure());
                     } else {
                         ASSERT(variant.kind() == PutByIdVariant::Replace);
index 11f4c6b..030934d 100644 (file)
@@ -51,7 +51,7 @@ void AbstractValue::setOSREntryValue(Graph& graph, const FrozenValue& value)
 {
     if (!!value && value.value().isCell()) {
         Structure* structure = value.structure();
-        graph.watchpoints().consider(structure);
+        graph.registerStructure(structure);
         m_structure = structure;
         m_arrayModes = asArrayModes(structure->indexingType());
     } else {
@@ -63,18 +63,17 @@ void AbstractValue::setOSREntryValue(Graph& graph, const FrozenValue& value)
     m_value = value.value();
         
     checkConsistency();
-    assertIsWatched(graph);
+    assertIsRegistered(graph);
 }
 
 void AbstractValue::set(Graph& graph, const FrozenValue& value, StructureClobberState clobberState)
 {
     if (!!value && value.value().isCell()) {
         Structure* structure = value.structure();
-        if (graph.watchpoints().consider(structure)) {
-            // We should be able to assume that the watchpoint for this has already been set.
-            // But we can't because our view of what structure a value has keeps changing. That's
-            // why we call consider().
-            // https://bugs.webkit.org/show_bug.cgi?id=133426
+        // FIXME: This check may not be necessary since any frozen value should have its structure
+        // watched already.
+        // https://bugs.webkit.org/show_bug.cgi?id=136055
+        if (graph.registerStructure(structure) == StructureRegisteredAndWatched) {
             m_structure = structure;
             if (clobberState == StructuresAreClobbered) {
                 m_arrayModes = ALL_ARRAY_MODES;
@@ -94,7 +93,7 @@ void AbstractValue::set(Graph& graph, const FrozenValue& value, StructureClobber
     m_value = value.value();
     
     checkConsistency();
-    assertIsWatched(graph);
+    assertIsRegistered(graph);
 }
 
 void AbstractValue::set(Graph& graph, Structure* structure)
@@ -105,7 +104,7 @@ void AbstractValue::set(Graph& graph, Structure* structure)
     m_value = JSValue();
     
     checkConsistency();
-    assertIsWatched(graph);
+    assertIsRegistered(graph);
 }
 
 void AbstractValue::set(Graph& graph, const StructureSet& set)
@@ -116,7 +115,7 @@ void AbstractValue::set(Graph& graph, const StructureSet& set)
     m_value = JSValue();
     
     checkConsistency();
-    assertIsWatched(graph);
+    assertIsRegistered(graph);
 }
 
 void AbstractValue::fixTypeForRepresentation(NodeFlags representation)
@@ -364,7 +363,7 @@ FiltrationResult AbstractValue::normalizeClarity()
 FiltrationResult AbstractValue::normalizeClarity(Graph& graph)
 {
     FiltrationResult result = normalizeClarity();
-    assertIsWatched(graph);
+    assertIsRegistered(graph);
     return result;
 }
 
@@ -394,9 +393,9 @@ void AbstractValue::checkConsistency() const
     // complexity of the code.
 }
 
-void AbstractValue::assertIsWatched(Graph& graph) const
+void AbstractValue::assertIsRegistered(Graph& graph) const
 {
-    m_structure.assertIsWatched(graph);
+    m_structure.assertIsRegistered(graph);
 }
 #endif
 
index 0a9cdd3..2608acb 100644 (file)
@@ -321,10 +321,10 @@ struct AbstractValue {
     
 #if ASSERT_DISABLED
     void checkConsistency() const { }
-    void assertIsWatched(Graph&) const { }
+    void assertIsRegistered(Graph&) const { }
 #else
     void checkConsistency() const;
-    void assertIsWatched(Graph&) const;
+    void assertIsRegistered(Graph&) const;
 #endif
     
     void dumpInContext(PrintStream&, DumpContext*) const;
index c2574f2..417d7ab 100644 (file)
@@ -146,7 +146,9 @@ enum PredictionPass {
     FixupPass
 };
 
-enum StructureWatchpointState { HaveNotStartedWatching, WatchingAllWatchableStructures };
+enum StructureRegistrationState { HaveNotStartedRegistering, AllStructuresAreRegistered };
+
+enum StructureRegistrationResult { StructureRegisteredNormally, StructureRegisteredAndWatched };
 
 enum OptimizationFixpointState { BeforeFixpoint, FixpointNotConverged, FixpointConverged };
 
index ea9a7a3..ddbeca0 100644 (file)
@@ -571,8 +571,10 @@ private:
 
     void addStructureTransitionCheck(NodeOrigin origin, unsigned indexInBlock, JSCell* cell, Structure* structure)
     {
-        if (m_graph.watchpoints().consider(cell->structure()))
+        if (m_graph.registerStructure(cell->structure()) == StructureRegisteredAndWatched)
             return;
+        
+        m_graph.registerStructure(structure);
 
         Node* weakConstant = m_insertionSet.insertNode(
             indexInBlock, speculationFromValue(cell), JSConstant, origin,
index 6c6adf4..f14968c 100644 (file)
@@ -50,13 +50,17 @@ DesiredWeakReferences::~DesiredWeakReferences()
 
 void DesiredWeakReferences::addLazily(JSCell* cell)
 {
-    m_references.append(cell);
+    m_references.add(cell);
+}
+
+bool DesiredWeakReferences::contains(JSCell* cell)
+{
+    return m_references.contains(cell);
 }
 
 void DesiredWeakReferences::reallyAdd(VM& vm, CommonData* common)
 {
-    for (unsigned i = 0; i < m_references.size(); i++) {
-        JSCell* target = m_references[i];
+    for (JSCell* target : m_references) {
         if (Structure* structure = jsDynamicCast<Structure*>(target)) {
             common->weakStructureReferences.append(
                 WriteBarrier<Structure>(vm, m_codeBlock->ownerExecutable(), structure));
@@ -69,8 +73,8 @@ void DesiredWeakReferences::reallyAdd(VM& vm, CommonData* common)
 
 void DesiredWeakReferences::visitChildren(SlotVisitor& visitor)
 {
-    for (unsigned i = m_references.size(); i--;)
-        visitor.appendUnbarrieredPointer(&m_references[i]);
+    for (JSCell* target : m_references)
+        visitor.appendUnbarrieredPointer(&target);
 }
 
 } } // namespace JSC::DFG
index 48ad44c..e312255 100644 (file)
@@ -26,7 +26,7 @@
 #ifndef DFGDesiredWeakReferences_h
 #define DFGDesiredWeakReferences_h
 
-#include <wtf/Vector.h>
+#include <wtf/HashSet.h>
 
 #if ENABLE(DFG_JIT)
 
@@ -48,13 +48,15 @@ public:
     ~DesiredWeakReferences();
 
     void addLazily(JSCell*);
+    bool contains(JSCell*);
+    
     void reallyAdd(VM&, CommonData*);
     
     void visitChildren(SlotVisitor&);
 
 private:
     CodeBlock* m_codeBlock;
-    Vector<JSCell*> m_references;
+    HashSet<JSCell*> m_references;
 };
 
 } } // namespace JSC::DFG
index b5ae361..2f748f8 100644 (file)
@@ -1393,7 +1393,7 @@ private:
         
         JSObject* stringPrototypeObject = asObject(stringObjectStructure->storedPrototype());
         Structure* stringPrototypeStructure = stringPrototypeObject->structure();
-        if (!m_graph.watchpoints().consider(stringPrototypeStructure))
+        if (m_graph.registerStructure(stringPrototypeStructure) != StructureRegisteredAndWatched)
             return false;
         
         if (stringPrototypeStructure->isDictionary())
index 23c6280..1fedfbe 100644 (file)
@@ -65,7 +65,7 @@ Graph::Graph(VM& vm, Plan& plan, LongLivedState& longLivedState)
     , m_nextMachineLocal(0)
     , m_machineCaptureStart(std::numeric_limits<int>::max())
     , m_fixpointState(BeforeFixpoint)
-    , m_structureWatchpointState(HaveNotStartedWatching)
+    , m_structureRegistrationState(HaveNotStartedRegistering)
     , m_form(LoadStore)
     , m_unificationState(LocallyUnified)
     , m_refCountState(EverythingIsLive)
@@ -943,8 +943,8 @@ void Graph::registerFrozenValues()
 {
     m_codeBlock->constants().resize(0);
     for (FrozenValue* value : m_frozenValues) {
-        if (value->structure() && value->structure()->dfgShouldWatch())
-            m_plan.weakReferences.addLazily(value->structure());
+        if (value->structure())
+            ASSERT(m_plan.weakReferences.contains(value->structure()));
         
         switch (value->strength()) {
         case FragileValue: {
@@ -1071,7 +1071,7 @@ FrozenValue* Graph::freezeStrong(JSValue value)
 void Graph::convertToConstant(Node* node, FrozenValue* value)
 {
     if (value->structure())
-        assertIsWatched(value->structure());
+        assertIsRegistered(value->structure());
     if (m_form == ThreadedCPS) {
         if (node->op() == GetLocal)
             dethread();
@@ -1091,11 +1091,21 @@ void Graph::convertToStrongConstant(Node* node, JSValue value)
     convertToConstant(node, freezeStrong(value));
 }
 
-void Graph::assertIsWatched(Structure* structure)
+StructureRegistrationResult Graph::registerStructure(Structure* structure)
 {
-    if (m_structureWatchpointState == HaveNotStartedWatching)
+    m_plan.weakReferences.addLazily(structure);
+    if (m_plan.watchpoints.consider(structure))
+        return StructureRegisteredAndWatched;
+    return StructureRegisteredNormally;
+}
+
+void Graph::assertIsRegistered(Structure* structure)
+{
+    if (m_structureRegistrationState == HaveNotStartedRegistering)
         return;
     
+    DFG_ASSERT(*this, nullptr, m_plan.weakReferences.contains(structure));
+    
     if (!structure->dfgShouldWatch())
         return;
     if (watchpoints().isWatched(structure->transitionWatchpointSet()))
index e612642..55a0c6e 100644 (file)
@@ -154,7 +154,8 @@ public:
     void convertToConstant(Node* node, JSValue value);
     void convertToStrongConstant(Node* node, JSValue value);
     
-    void assertIsWatched(Structure* structure);
+    StructureRegistrationResult registerStructure(Structure* structure);
+    void assertIsRegistered(Structure* structure);
     
     // CodeBlock is optional, but may allow additional information to be dumped (e.g. Identifier names).
     void dump(PrintStream& = WTF::dataFile(), DumpContext* = 0);
@@ -757,7 +758,7 @@ public:
 #endif
     
     OptimizationFixpointState m_fixpointState;
-    StructureWatchpointState m_structureWatchpointState;
+    StructureRegistrationState m_structureRegistrationState;
     GraphForm m_form;
     UnificationState m_unificationState;
     RefCountState m_refCountState;
index 3feefbd..7b4d937 100644 (file)
 #include "DFGStaticExecutionCountEstimationPhase.h"
 #include "DFGStoreBarrierElisionPhase.h"
 #include "DFGStrengthReductionPhase.h"
+#include "DFGStructureRegistrationPhase.h"
 #include "DFGTierUpCheckInjectionPhase.h"
 #include "DFGTypeCheckHoistingPhase.h"
 #include "DFGUnificationPhase.h"
 #include "DFGValidate.h"
 #include "DFGVirtualRegisterAllocationPhase.h"
-#include "DFGWatchableStructureWatchingPhase.h"
 #include "DFGWatchpointCollectionPhase.h"
 #include "Debugger.h"
 #include "JSCInlines.h"
@@ -237,7 +237,7 @@ Plan::CompilationPath Plan::compileInThreadImpl(LongLivedState& longLivedState)
     performBackwardsPropagation(dfg);
     performPredictionPropagation(dfg);
     performFixup(dfg);
-    performWatchableStructureWatching(dfg);
+    performStructureRegistration(dfg);
     performInvalidationPointInjection(dfg);
     performTypeCheckHoisting(dfg);
     
index 88baea7..b96e781 100644 (file)
@@ -38,15 +38,15 @@ namespace JSC { namespace DFG {
 //#define SAMPLE(name) SamplingRegion samplingRegion(name)
 
 #if !ASSERT_DISABLED
-void StructureAbstractValue::assertIsWatched(Graph& graph) const
+void StructureAbstractValue::assertIsRegistered(Graph& graph) const
 {
-    SAMPLE("StructureAbstractValue assertIsWatched");
+    SAMPLE("StructureAbstractValue assertIsRegistered");
 
     if (isTop())
         return;
     
     for (unsigned i = size(); i--;)
-        graph.assertIsWatched(at(i));
+        graph.assertIsRegistered(at(i));
 }
 #endif // !ASSERT_DISABLED
 
index 8128a1c..dc22186 100644 (file)
@@ -87,9 +87,9 @@ public:
     }
     
 #if ASSERT_DISABLED
-    void assertIsWatched(Graph&) const { }
+    void assertIsRegistered(Graph&) const { }
 #else
-    void assertIsWatched(Graph&) const;
+    void assertIsRegistered(Graph&) const;
 #endif
     
     void clobber();
@@ -24,7 +24,7 @@
  */
 
 #include "config.h"
-#include "DFGWatchableStructureWatchingPhase.h"
+#include "DFGStructureRegistrationPhase.h"
 
 #if ENABLE(DFG_JIT)
 
 
 namespace JSC { namespace DFG {
 
-class WatchableStructureWatchingPhase : public Phase {
+class StructureRegistrationPhase : public Phase {
 public:
-    WatchableStructureWatchingPhase(Graph& graph)
-        : Phase(graph, "watchable structure watching")
+    StructureRegistrationPhase(Graph& graph)
+        : Phase(graph, "structure registration")
     {
     }
     
     bool run()
     {
-        // These are pretty dumb, but needed to placate subsequent assertions. We con't actually
+        // These are pretty dumb, but needed to placate subsequent assertions. We don't actually
         // have to watch these because there is no way to transition away from it, but they are
         // watchable and so we will assert if they aren't watched.
-        tryWatch(m_graph.m_vm.stringStructure.get());
-        tryWatch(m_graph.m_vm.getterSetterStructure.get());
+        registerStructure(m_graph.m_vm.stringStructure.get());
+        registerStructure(m_graph.m_vm.getterSetterStructure.get());
         
         for (FrozenValue* value : m_graph.m_frozenValues)
-            tryWatch(value->structure());
+            registerStructure(value->structure());
         
         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
             BasicBlock* block = m_graph.block(blockIndex);
@@ -63,30 +63,30 @@ public:
             
                 switch (node->op()) {
                 case CheckExecutable:
-                    tryWatch(node->executable()->structure());
+                    registerStructure(node->executable()->structure());
                     break;
                 
                 case CheckStructure:
-                    tryWatch(node->structureSet());
+                    registerStructures(node->structureSet());
                     break;
                 
                 case NewObject:
                 case ArrayifyToStructure:
                 case NewStringObject:
-                    tryWatch(node->structure());
+                    registerStructure(node->structure());
                     break;
                 
                 case PutStructure:
                 case AllocatePropertyStorage:
                 case ReallocatePropertyStorage:
-                    RELEASE_ASSERT(node->transition()->previous->transitionWatchpointSetHasBeenInvalidated());
-                    tryWatch(node->transition()->next);
+                    registerStructure(node->transition()->previous);
+                    registerStructure(node->transition()->next);
                     break;
                     
                 case MultiGetByOffset:
                     for (unsigned i = node->multiGetByOffsetData().variants.size(); i--;) {
                         GetByIdVariant& variant = node->multiGetByOffsetData().variants[i];
-                        tryWatch(variant.structureSet());
+                        registerStructures(variant.structureSet());
                         // Don't need to watch anything in the structure chain because that would
                         // have been decomposed into CheckStructure's. Don't need to watch the
                         // callLinkStatus because we wouldn't use MultiGetByOffset if any of the
@@ -98,31 +98,36 @@ public:
                 case MultiPutByOffset:
                     for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
                         PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
-                        tryWatch(variant.oldStructure());
+                        registerStructures(variant.oldStructure());
                         if (variant.kind() == PutByIdVariant::Transition)
-                            tryWatch(variant.newStructure());
+                            registerStructure(variant.newStructure());
                     }
                     break;
                     
                 case NewArray:
                 case NewArrayBuffer:
-                    tryWatch(m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
+                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
                     break;
                     
                 case NewTypedArray:
-                    tryWatch(m_graph.globalObjectFor(node->origin.semantic)->typedArrayStructure(node->typedArrayType()));
+                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->typedArrayStructure(node->typedArrayType()));
                     break;
                     
                 case ToString:
-                    tryWatch(m_graph.globalObjectFor(node->origin.semantic)->stringObjectStructure());
+                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->stringObjectStructure());
                     break;
                     
                 case CreateActivation:
-                    tryWatch(m_graph.globalObjectFor(node->origin.semantic)->activationStructure());
+                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->activationStructure());
                     break;
                     
                 case NewRegexp:
-                    tryWatch(m_graph.globalObjectFor(node->origin.semantic)->regExpStructure());
+                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->regExpStructure());
+                    break;
+                    
+                case NewFunctionExpression:
+                case NewFunctionNoCheck:
+                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->functionStructure());
                     break;
                     
                 default:
@@ -131,29 +136,29 @@ public:
             }
         }
         
-        m_graph.m_structureWatchpointState = WatchingAllWatchableStructures;
+        m_graph.m_structureRegistrationState = AllStructuresAreRegistered;
         
         return true;
     }
 
 private:
-    void tryWatch(const StructureSet& set)
+    void registerStructures(const StructureSet& set)
     {
         for (unsigned i = set.size(); i--;)
-            tryWatch(set[i]);
+            registerStructure(set[i]);
     }
     
-    void tryWatch(Structure* structure)
+    void registerStructure(Structure* structure)
     {
         if (structure)
-            m_graph.watchpoints().consider(structure);
+            m_graph.registerStructure(structure);
     }
 };
 
-bool performWatchableStructureWatching(Graph& graph)
+bool performStructureRegistration(Graph& graph)
 {
-    SamplingRegion samplingRegion("DFG Watchable Structure Watching");
-    return runPhase<WatchableStructureWatchingPhase>(graph);
+    SamplingRegion samplingRegion("DFG Structure Registration Phase");
+    return runPhase<StructureRegistrationPhase>(graph);
 }
 
 } } // namespace JSC::DFG
@@ -23,8 +23,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#ifndef DFGWatchableStructureWatchingPhase_h
-#define DFGWatchableStructureWatchingPhase_h
+#ifndef DFGStructureRegistrationPhase_h
+#define DFGStructureRegistrationPhase_h
 
 #if ENABLE(DFG_JIT)
 
@@ -32,9 +32,10 @@ namespace JSC { namespace DFG {
 
 class Graph;
 
-// Set watchpoints on any structures that we know of that are currently watchable. It's
-// somewhat counterintuitive, but this ends up being the cleanest and most effective way
-// of reducing structure checks on terminal structures:
+// Registers any structures we know about as weak references, and sets watchpoints on any
+// such structures that we know of that are currently watchable. It's somewhat
+// counterintuitive, but this ends up being the cleanest and most effective way of reducing
+// structure checks on terminal structures:
 //
 // - We used to only set watchpoints on watchable structures if we knew that this would
 //   remove a structure check. Experiments show that switching from that, to blindly
@@ -43,11 +44,11 @@ class Graph;
 // - It makes abstract interpretation a whole lot easier. We just assume that watchable
 //   structures are unclobberable without having to do any other logic.
 
-bool performWatchableStructureWatching(Graph&);
+bool performStructureRegistration(Graph&);
 
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)
 
-#endif // DFGWatchableStructureWatchingPhase_h
+#endif // DFGStructureRegistrationPhase_h