Title: [186691] trunk/Source/_javascript_Core
Revision
186691
Author
[email protected]
Date
2015-07-10 14:19:51 -0700 (Fri, 10 Jul 2015)

Log Message

DFG fragile frozen values are fundamentally broken
https://bugs.webkit.org/show_bug.cgi?id=146602

Reviewed by Mark Lam.
        
This change gets rid of the FragileValue value strength, because it was fundamentally
broken.
        
FragileValue was a value known to the compiler but not tracked by the GC in any way -
it wasn't marked and it wasn't weak. This was used to support AI bootstrap for OSR
must-handle values. The philosophy was that if the compiler did use the value for
optimization, it would have been strengthened to a weak value (or maybe even a strong
value, though we probably won't do that). But this was too much of a pipe dream. I've
found at least one case where the compiler did use the value, but never strengthened
it: it would happen if the value ended up in an OSR entry data expected value. Then if
we GCed, we might have killed the value, but OSR entry would still try to use it for
validation. That might have sort of just worked, but it's clearly shady.

The reason why we made must-handle values fragile and not weak is that most of the time
the values disappear from the abstract state: they are LUBed to a non-constant. If we
kept them around as weak, we'd have too many cases of the GC killing the code because
it thought that the value was somehow meaningful to the code when it was only used as a
temporary artifact of optimization.

So, it's true that it's very important for must-handle values not to automatically be
weak or strong. It's also true that the values are necessary for AI bootstrap because
we need to know what values OSR entry will require. But we shouldn't accomplish these
goals by having the compiler hold onto what are essentially dangling pointers.
        
This implements a better solution: instead of having InPlaceAbstractState bootstrap the
AI with must-handle values at the beginning, we now widen the valuesAtHead of the
must-handle block after AI converges. This widening is done in CFAPhase. This allows us
to see if the must-handle values are necessary at all. In most cases, the widening
takes a non-constant abstract value and simply amends something to its type based on
the type of the must-handle value, and so the must-handle value never actually shows up
in either the IR or any abstract value. In the unlikely event that the value at head is
bottom, we freeze the must-handle value. This change removes FragileValue, and this
freezing uses WeakValue as the strength. That makes sense: since the abstract value was
bottom, the must-handle value becomes integral to the IR and so it makes no sense for
the GC to keep the resulting CodeBlock alive if that must-handle value dies. This will
sometimes happen for example if you have a very long-running loop whose pre-header
allocates some object, but that pre-header appears to always exit to the optimizing JIT
because it was only profiled once in the LLInt and that profiling appears insufficient
to the DFG. In that case, we'll effectively constant-fold the references to the object
inside the loop, which is both efficient (yay constant folding!) and necessary
(otherwise we wouldn't know what the type of the variable should have been).
        
Testing and debugging this is complicated. So, this adds some new capabilities:
        
- DFG IR dumps also dump all of the FrozenValues that point to the heap along with
  their strengths, so that it's easy to see what GC objects the DFG feels are necessary
  for the compilation.
        
- DFG OSR entry preparation prints out the OSR entry data structures, so that it's easy
  to see what GC pointers (and other things) are used for OSR entry validation. The
  printouts are quite detailed, and should also help other kinds of OSR entry
  debugging.
        
- DFG::Plan now validates whether all of the GC pointers planted in the various JITCode
  data structures are also properly registered as either weak or strong pointers in the
  CodeBlock. This validation check previously failed due to fragile values ending up in
  the OSR entry data structures, both in the newly added test (dead-osr-entry-value.js)
  and in some pre-existing tests (like earley-boyer and 3d-raytrace).

* CMakeLists.txt:
* _javascript_Core.vcxproj/_javascript_Core.vcxproj:
* _javascript_Core.xcodeproj/project.pbxproj:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::stronglyVisitStrongReferences):
* bytecode/CodeOrigin.cpp:
(JSC::InlineCallFrame::visitAggregate):
* bytecode/Operands.h:
(JSC::Operands::operand):
(JSC::Operands::hasOperand):
* bytecode/StructureSet.cpp:
(JSC::StructureSet::dump):
(JSC::StructureSet::validateReferences):
* bytecode/StructureSet.h:
* bytecode/TrackedReferences.cpp: Added.
(JSC::TrackedReferences::TrackedReferences):
(JSC::TrackedReferences::~TrackedReferences):
(JSC::TrackedReferences::add):
(JSC::TrackedReferences::check):
(JSC::TrackedReferences::dump):
* bytecode/TrackedReferences.h: Added.
* dfg/DFGAbstractValue.cpp:
(JSC::DFG::AbstractValue::observeTransitions):
(JSC::DFG::AbstractValue::set):
(JSC::DFG::AbstractValue::fixTypeForRepresentation):
(JSC::DFG::AbstractValue::mergeOSREntryValue):
(JSC::DFG::AbstractValue::filter):
(JSC::DFG::AbstractValue::dumpInContext):
(JSC::DFG::AbstractValue::validateReferences):
(JSC::DFG::AbstractValue::setOSREntryValue): Deleted.
* dfg/DFGAbstractValue.h:
(JSC::DFG::AbstractValue::fullTop):
(JSC::DFG::AbstractValue::merge):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
* dfg/DFGCFAPhase.cpp:
(JSC::DFG::CFAPhase::run):
* dfg/DFGCommonData.cpp:
(JSC::DFG::CommonData::invalidate):
(JSC::DFG::CommonData::validateReferences):
* dfg/DFGCommonData.h:
(JSC::DFG::CommonData::requiredRegisterCountForExecutionAndExit):
* dfg/DFGFrozenValue.h:
(JSC::DFG::FrozenValue::FrozenValue):
(JSC::DFG::FrozenValue::strengthenTo):
(JSC::DFG::FrozenValue::pointsToHeap):
(JSC::DFG::FrozenValue::strength):
(JSC::DFG::FrozenValue::freeze):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::Graph):
(JSC::DFG::Graph::dump):
(JSC::DFG::Graph::registerFrozenValues):
(JSC::DFG::Graph::visitChildren):
(JSC::DFG::Graph::freeze):
(JSC::DFG::Graph::freezeStrong):
(JSC::DFG::Graph::freezeFragile): Deleted.
* dfg/DFGGraph.h:
* dfg/DFGInPlaceAbstractState.cpp:
(JSC::DFG::InPlaceAbstractState::initialize):
* dfg/DFGJITCode.cpp:
(JSC::DFG::JITCode::setOptimizationThresholdBasedOnCompilationResult):
(JSC::DFG::JITCode::validateReferences):
* dfg/DFGJITCode.h:
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::addressOfDoubleConstant):
(JSC::DFG::JITCompiler::noticeOSREntry):
* dfg/DFGJITCompiler.h:
(JSC::DFG::JITCompiler::branchStructurePtr):
(JSC::DFG::JITCompiler::jitCode):
(JSC::DFG::JITCompiler::noticeOSREntry): Deleted.
* dfg/DFGMinifiedGraph.cpp: Added.
(JSC::DFG::MinifiedGraph::prepareAndShrink):
(JSC::DFG::MinifiedGraph::validateReferences):
* dfg/DFGMinifiedGraph.h:
(JSC::DFG::MinifiedGraph::append):
(JSC::DFG::MinifiedGraph::prepareAndShrink): Deleted.
* dfg/DFGOSREntry.cpp:
(JSC::DFG::OSREntryData::dumpInContext):
(JSC::DFG::OSREntryData::dump):
(JSC::DFG::prepareOSREntry):
* dfg/DFGOSREntry.h:
(JSC::DFG::getOSREntryDataBytecodeIndex):
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::finalizeWithoutNotifyingCallback):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::linkOSREntries):
(JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
* dfg/DFGStructureAbstractValue.cpp:
(JSC::DFG::StructureAbstractValue::dump):
(JSC::DFG::StructureAbstractValue::validateReferences):
* dfg/DFGStructureAbstractValue.h:
* dfg/DFGValidate.cpp:
(JSC::DFG::Validate::validate):
* dfg/DFGValueStrength.cpp:
(WTF::printInternal):
* dfg/DFGValueStrength.h:
(JSC::DFG::merge):
* ftl/FTLExitPropertyValue.cpp:
(JSC::FTL::ExitPropertyValue::dump):
(JSC::FTL::ExitPropertyValue::validateReferences):
* ftl/FTLExitPropertyValue.h:
* ftl/FTLExitTimeObjectMaterialization.cpp:
(JSC::FTL::ExitTimeObjectMaterialization::dump):
(JSC::FTL::ExitTimeObjectMaterialization::validateReferences):
* ftl/FTLExitTimeObjectMaterialization.h:
* ftl/FTLExitValue.cpp:
(JSC::FTL::ExitValue::dump):
(JSC::FTL::ExitValue::validateReferences):
* ftl/FTLExitValue.h:
* ftl/FTLJITCode.cpp:
(JSC::FTL::JITCode::dfgCommon):
(JSC::FTL::JITCode::validateReferences):
* ftl/FTLJITCode.h:
(JSC::FTL::JITCode::handles):
(JSC::FTL::JITCode::dataSections):
* ftl/FTLOSRExit.cpp:
(JSC::FTL::OSRExit::codeLocationForRepatch):
(JSC::FTL::OSRExit::validateReferences):
* ftl/FTLOSRExit.h:
(JSC::FTL::OSRExit::considerAddingAsFrequentExitSite):
* jit/JITCode.cpp:
(JSC::JITCode::typeName):
(JSC::JITCode::validateReferences):
(JSC::JITCode::execute):
* jit/JITCode.h:
(JSC::JITCode::start):
* tests/stress/dead-osr-entry-value.js: Added.
(foo):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/CMakeLists.txt (186690 => 186691)


--- trunk/Source/_javascript_Core/CMakeLists.txt	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/CMakeLists.txt	2015-07-10 21:19:51 UTC (rev 186691)
@@ -110,6 +110,7 @@
     bytecode/StructureStubClearingWatchpoint.cpp
     bytecode/StructureStubInfo.cpp
     bytecode/ToThisStatus.cpp
+    bytecode/TrackedReferences.cpp
     bytecode/UnlinkedCodeBlock.cpp
     bytecode/UnlinkedInstructionStream.cpp
     bytecode/ValueRecovery.cpp
@@ -193,6 +194,7 @@
     dfg/DFGLongLivedState.cpp
     dfg/DFGLoopPreHeaderCreationPhase.cpp
     dfg/DFGMayExit.cpp
+    dfg/DFGMinifiedGraph.cpp
     dfg/DFGMinifiedNode.cpp
     dfg/DFGMovHintRemovalPhase.cpp
     dfg/DFGNaiveDominators.cpp

Modified: trunk/Source/_javascript_Core/ChangeLog (186690 => 186691)


--- trunk/Source/_javascript_Core/ChangeLog	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-07-10 21:19:51 UTC (rev 186691)
@@ -1,3 +1,198 @@
+2015-07-04  Filip Pizlo  <[email protected]>
+
+        DFG fragile frozen values are fundamentally broken
+        https://bugs.webkit.org/show_bug.cgi?id=146602
+
+        Reviewed by Mark Lam.
+        
+        This change gets rid of the FragileValue value strength, because it was fundamentally
+        broken.
+        
+        FragileValue was a value known to the compiler but not tracked by the GC in any way -
+        it wasn't marked and it wasn't weak. This was used to support AI bootstrap for OSR
+        must-handle values. The philosophy was that if the compiler did use the value for
+        optimization, it would have been strengthened to a weak value (or maybe even a strong
+        value, though we probably won't do that). But this was too much of a pipe dream. I've
+        found at least one case where the compiler did use the value, but never strengthened
+        it: it would happen if the value ended up in an OSR entry data expected value. Then if
+        we GCed, we might have killed the value, but OSR entry would still try to use it for
+        validation. That might have sort of just worked, but it's clearly shady.
+
+        The reason why we made must-handle values fragile and not weak is that most of the time
+        the values disappear from the abstract state: they are LUBed to a non-constant. If we
+        kept them around as weak, we'd have too many cases of the GC killing the code because
+        it thought that the value was somehow meaningful to the code when it was only used as a
+        temporary artifact of optimization.
+
+        So, it's true that it's very important for must-handle values not to automatically be
+        weak or strong. It's also true that the values are necessary for AI bootstrap because
+        we need to know what values OSR entry will require. But we shouldn't accomplish these
+        goals by having the compiler hold onto what are essentially dangling pointers.
+        
+        This implements a better solution: instead of having InPlaceAbstractState bootstrap the
+        AI with must-handle values at the beginning, we now widen the valuesAtHead of the
+        must-handle block after AI converges. This widening is done in CFAPhase. This allows us
+        to see if the must-handle values are necessary at all. In most cases, the widening
+        takes a non-constant abstract value and simply amends something to its type based on
+        the type of the must-handle value, and so the must-handle value never actually shows up
+        in either the IR or any abstract value. In the unlikely event that the value at head is
+        bottom, we freeze the must-handle value. This change removes FragileValue, and this
+        freezing uses WeakValue as the strength. That makes sense: since the abstract value was
+        bottom, the must-handle value becomes integral to the IR and so it makes no sense for
+        the GC to keep the resulting CodeBlock alive if that must-handle value dies. This will
+        sometimes happen for example if you have a very long-running loop whose pre-header
+        allocates some object, but that pre-header appears to always exit to the optimizing JIT
+        because it was only profiled once in the LLInt and that profiling appears insufficient
+        to the DFG. In that case, we'll effectively constant-fold the references to the object
+        inside the loop, which is both efficient (yay constant folding!) and necessary
+        (otherwise we wouldn't know what the type of the variable should have been).
+        
+        Testing and debugging this is complicated. So, this adds some new capabilities:
+        
+        - DFG IR dumps also dump all of the FrozenValues that point to the heap along with
+          their strengths, so that it's easy to see what GC objects the DFG feels are necessary
+          for the compilation.
+        
+        - DFG OSR entry preparation prints out the OSR entry data structures, so that it's easy
+          to see what GC pointers (and other things) are used for OSR entry validation. The
+          printouts are quite detailed, and should also help other kinds of OSR entry
+          debugging.
+        
+        - DFG::Plan now validates whether all of the GC pointers planted in the various JITCode
+          data structures are also properly registered as either weak or strong pointers in the
+          CodeBlock. This validation check previously failed due to fragile values ending up in
+          the OSR entry data structures, both in the newly added test (dead-osr-entry-value.js)
+          and in some pre-existing tests (like earley-boyer and 3d-raytrace).
+
+        * CMakeLists.txt:
+        * _javascript_Core.vcxproj/_javascript_Core.vcxproj:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::stronglyVisitStrongReferences):
+        * bytecode/CodeOrigin.cpp:
+        (JSC::InlineCallFrame::visitAggregate):
+        * bytecode/Operands.h:
+        (JSC::Operands::operand):
+        (JSC::Operands::hasOperand):
+        * bytecode/StructureSet.cpp:
+        (JSC::StructureSet::dump):
+        (JSC::StructureSet::validateReferences):
+        * bytecode/StructureSet.h:
+        * bytecode/TrackedReferences.cpp: Added.
+        (JSC::TrackedReferences::TrackedReferences):
+        (JSC::TrackedReferences::~TrackedReferences):
+        (JSC::TrackedReferences::add):
+        (JSC::TrackedReferences::check):
+        (JSC::TrackedReferences::dump):
+        * bytecode/TrackedReferences.h: Added.
+        * dfg/DFGAbstractValue.cpp:
+        (JSC::DFG::AbstractValue::observeTransitions):
+        (JSC::DFG::AbstractValue::set):
+        (JSC::DFG::AbstractValue::fixTypeForRepresentation):
+        (JSC::DFG::AbstractValue::mergeOSREntryValue):
+        (JSC::DFG::AbstractValue::filter):
+        (JSC::DFG::AbstractValue::dumpInContext):
+        (JSC::DFG::AbstractValue::validateReferences):
+        (JSC::DFG::AbstractValue::setOSREntryValue): Deleted.
+        * dfg/DFGAbstractValue.h:
+        (JSC::DFG::AbstractValue::fullTop):
+        (JSC::DFG::AbstractValue::merge):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+        * dfg/DFGCFAPhase.cpp:
+        (JSC::DFG::CFAPhase::run):
+        * dfg/DFGCommonData.cpp:
+        (JSC::DFG::CommonData::invalidate):
+        (JSC::DFG::CommonData::validateReferences):
+        * dfg/DFGCommonData.h:
+        (JSC::DFG::CommonData::requiredRegisterCountForExecutionAndExit):
+        * dfg/DFGFrozenValue.h:
+        (JSC::DFG::FrozenValue::FrozenValue):
+        (JSC::DFG::FrozenValue::strengthenTo):
+        (JSC::DFG::FrozenValue::pointsToHeap):
+        (JSC::DFG::FrozenValue::strength):
+        (JSC::DFG::FrozenValue::freeze):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::Graph):
+        (JSC::DFG::Graph::dump):
+        (JSC::DFG::Graph::registerFrozenValues):
+        (JSC::DFG::Graph::visitChildren):
+        (JSC::DFG::Graph::freeze):
+        (JSC::DFG::Graph::freezeStrong):
+        (JSC::DFG::Graph::freezeFragile): Deleted.
+        * dfg/DFGGraph.h:
+        * dfg/DFGInPlaceAbstractState.cpp:
+        (JSC::DFG::InPlaceAbstractState::initialize):
+        * dfg/DFGJITCode.cpp:
+        (JSC::DFG::JITCode::setOptimizationThresholdBasedOnCompilationResult):
+        (JSC::DFG::JITCode::validateReferences):
+        * dfg/DFGJITCode.h:
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::addressOfDoubleConstant):
+        (JSC::DFG::JITCompiler::noticeOSREntry):
+        * dfg/DFGJITCompiler.h:
+        (JSC::DFG::JITCompiler::branchStructurePtr):
+        (JSC::DFG::JITCompiler::jitCode):
+        (JSC::DFG::JITCompiler::noticeOSREntry): Deleted.
+        * dfg/DFGMinifiedGraph.cpp: Added.
+        (JSC::DFG::MinifiedGraph::prepareAndShrink):
+        (JSC::DFG::MinifiedGraph::validateReferences):
+        * dfg/DFGMinifiedGraph.h:
+        (JSC::DFG::MinifiedGraph::append):
+        (JSC::DFG::MinifiedGraph::prepareAndShrink): Deleted.
+        * dfg/DFGOSREntry.cpp:
+        (JSC::DFG::OSREntryData::dumpInContext):
+        (JSC::DFG::OSREntryData::dump):
+        (JSC::DFG::prepareOSREntry):
+        * dfg/DFGOSREntry.h:
+        (JSC::DFG::getOSREntryDataBytecodeIndex):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::finalizeWithoutNotifyingCallback):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::linkOSREntries):
+        (JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
+        * dfg/DFGStructureAbstractValue.cpp:
+        (JSC::DFG::StructureAbstractValue::dump):
+        (JSC::DFG::StructureAbstractValue::validateReferences):
+        * dfg/DFGStructureAbstractValue.h:
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validate):
+        * dfg/DFGValueStrength.cpp:
+        (WTF::printInternal):
+        * dfg/DFGValueStrength.h:
+        (JSC::DFG::merge):
+        * ftl/FTLExitPropertyValue.cpp:
+        (JSC::FTL::ExitPropertyValue::dump):
+        (JSC::FTL::ExitPropertyValue::validateReferences):
+        * ftl/FTLExitPropertyValue.h:
+        * ftl/FTLExitTimeObjectMaterialization.cpp:
+        (JSC::FTL::ExitTimeObjectMaterialization::dump):
+        (JSC::FTL::ExitTimeObjectMaterialization::validateReferences):
+        * ftl/FTLExitTimeObjectMaterialization.h:
+        * ftl/FTLExitValue.cpp:
+        (JSC::FTL::ExitValue::dump):
+        (JSC::FTL::ExitValue::validateReferences):
+        * ftl/FTLExitValue.h:
+        * ftl/FTLJITCode.cpp:
+        (JSC::FTL::JITCode::dfgCommon):
+        (JSC::FTL::JITCode::validateReferences):
+        * ftl/FTLJITCode.h:
+        (JSC::FTL::JITCode::handles):
+        (JSC::FTL::JITCode::dataSections):
+        * ftl/FTLOSRExit.cpp:
+        (JSC::FTL::OSRExit::codeLocationForRepatch):
+        (JSC::FTL::OSRExit::validateReferences):
+        * ftl/FTLOSRExit.h:
+        (JSC::FTL::OSRExit::considerAddingAsFrequentExitSite):
+        * jit/JITCode.cpp:
+        (JSC::JITCode::typeName):
+        (JSC::JITCode::validateReferences):
+        (JSC::JITCode::execute):
+        * jit/JITCode.h:
+        (JSC::JITCode::start):
+        * tests/stress/dead-osr-entry-value.js: Added.
+        (foo):
+
 2015-07-09  Filip Pizlo  <[email protected]>
 
         It should be possible to run the OSR exit fuzzer

Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj (186690 => 186691)


--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj	2015-07-10 21:19:51 UTC (rev 186691)
@@ -351,6 +351,7 @@
     <ClCompile Include="..\bytecode\StructureStubClearingWatchpoint.cpp" />
     <ClCompile Include="..\bytecode\StructureStubInfo.cpp" />
     <ClCompile Include="..\bytecode\ToThisStatus.cpp" />
+    <ClCompile Include="..\bytecode\TrackedReferences.cpp" />
     <ClCompile Include="..\bytecode\UnlinkedCodeBlock.cpp" />
     <ClCompile Include="..\bytecode\UnlinkedInstructionStream.cpp" />
     <ClCompile Include="..\bytecode\ValueRecovery.cpp" />
@@ -431,6 +432,7 @@
     <ClCompile Include="..\dfg\DFGLongLivedState.cpp" />
     <ClCompile Include="..\dfg\DFGLoopPreHeaderCreationPhase.cpp" />
     <ClCompile Include="..\dfg\DFGMayExit.cpp" />
+    <ClCompile Include="..\dfg\DFGMinifiedGraph.cpp" />
     <ClCompile Include="..\dfg\DFGMinifiedNode.cpp" />
     <ClCompile Include="..\dfg\DFGMovHintRemovalPhase.cpp" />
     <ClCompile Include="..\dfg\DFGNaiveDominators.cpp" />
@@ -1012,6 +1014,7 @@
     <ClInclude Include="..\bytecode\StructureStubClearingWatchpoint.h" />
     <ClInclude Include="..\bytecode\StructureStubInfo.h" />
     <ClInclude Include="..\bytecode\ToThisStatus.h" />
+    <ClInclude Include="..\bytecode\TrackedReferences.h" />
     <ClInclude Include="..\bytecode\TypeLocation.h" />
     <ClInclude Include="..\bytecode\UnlinkedCodeBlock.h" />
     <ClInclude Include="..\bytecode\UnlinkedInstructionStream.h" />

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (186690 => 186691)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2015-07-10 21:19:51 UTC (rev 186691)
@@ -106,6 +106,7 @@
 		0F13912C16771C3D009CCB07 /* ProfilerProfiledBytecodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F13912716771C30009CCB07 /* ProfilerProfiledBytecodes.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F13E04E16164A1F00DC8DE7 /* IndexingType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F13E04C16164A1B00DC8DE7 /* IndexingType.cpp */; };
 		0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0F1725FF1B48719A00AC3A55 /* DFGMinifiedGraph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F1725FE1B48719A00AC3A55 /* DFGMinifiedGraph.cpp */; };
 		0F190CAC189D82F6000AE5F0 /* ProfilerJettisonReason.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F190CAA189D82F6000AE5F0 /* ProfilerJettisonReason.cpp */; };
 		0F190CAD189D82F6000AE5F0 /* ProfilerJettisonReason.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F190CAB189D82F6000AE5F0 /* ProfilerJettisonReason.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F1DD84A18A945BE0026F3FA /* JSCInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F1DD84918A945BE0026F3FA /* JSCInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -451,6 +452,8 @@
 		0F9332A514CA7DDD0085F3C6 /* StructureSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F93329B14CA7DC10085F3C6 /* StructureSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F93B4A918B92C4D00178A3F /* PutByIdVariant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F93B4A718B92C4D00178A3F /* PutByIdVariant.cpp */; };
 		0F93B4AA18B92C4D00178A3F /* PutByIdVariant.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F93B4A818B92C4D00178A3F /* PutByIdVariant.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0F952ABC1B487A7700C367C5 /* TrackedReferences.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F952ABA1B487A7700C367C5 /* TrackedReferences.cpp */; };
+		0F952ABD1B487A7700C367C5 /* TrackedReferences.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F952ABB1B487A7700C367C5 /* TrackedReferences.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F96EBB316676EF6008BADE3 /* CodeBlockWithJITType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F96EBB116676EF4008BADE3 /* CodeBlockWithJITType.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F9749711687ADE400A4FF6A /* JSCellInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F97496F1687ADE200A4FF6A /* JSCellInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -1848,6 +1851,7 @@
 		0F13912716771C30009CCB07 /* ProfilerProfiledBytecodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerProfiledBytecodes.h; path = profiler/ProfilerProfiledBytecodes.h; sourceTree = "<group>"; };
 		0F13E04C16164A1B00DC8DE7 /* IndexingType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IndexingType.cpp; sourceTree = "<group>"; };
 		0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonSlowPaths.h; sourceTree = "<group>"; };
+		0F1725FE1B48719A00AC3A55 /* DFGMinifiedGraph.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGMinifiedGraph.cpp; path = dfg/DFGMinifiedGraph.cpp; sourceTree = "<group>"; };
 		0F190CAA189D82F6000AE5F0 /* ProfilerJettisonReason.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerJettisonReason.cpp; path = profiler/ProfilerJettisonReason.cpp; sourceTree = "<group>"; };
 		0F190CAB189D82F6000AE5F0 /* ProfilerJettisonReason.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerJettisonReason.h; path = profiler/ProfilerJettisonReason.h; sourceTree = "<group>"; };
 		0F1DD84918A945BE0026F3FA /* JSCInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCInlines.h; sourceTree = "<group>"; };
@@ -2191,6 +2195,8 @@
 		0F93329B14CA7DC10085F3C6 /* StructureSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureSet.h; sourceTree = "<group>"; };
 		0F93B4A718B92C4D00178A3F /* PutByIdVariant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PutByIdVariant.cpp; sourceTree = "<group>"; };
 		0F93B4A818B92C4D00178A3F /* PutByIdVariant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PutByIdVariant.h; sourceTree = "<group>"; };
+		0F952ABA1B487A7700C367C5 /* TrackedReferences.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TrackedReferences.cpp; sourceTree = "<group>"; };
+		0F952ABB1B487A7700C367C5 /* TrackedReferences.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackedReferences.h; sourceTree = "<group>"; };
 		0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueProfile.h; sourceTree = "<group>"; };
 		0F96EBB116676EF4008BADE3 /* CodeBlockWithJITType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeBlockWithJITType.h; sourceTree = "<group>"; };
 		0F97496F1687ADE200A4FF6A /* JSCellInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCellInlines.h; sourceTree = "<group>"; };
@@ -5002,6 +5008,7 @@
 				0F5874EB194FEB1200AAB2C1 /* DFGMayExit.cpp */,
 				0F5874EC194FEB1200AAB2C1 /* DFGMayExit.h */,
 				A704D90217A0BAA8006BA554 /* DFGMergeMode.h */,
+				0F1725FE1B48719A00AC3A55 /* DFGMinifiedGraph.cpp */,
 				0F2BDC3D1522801700CD8910 /* DFGMinifiedGraph.h */,
 				0FB4B51016B3A964003F696B /* DFGMinifiedID.h */,
 				0F2BDC4C1522818300CD8910 /* DFGMinifiedNode.cpp */,
@@ -5284,6 +5291,8 @@
 				0F426A4A1460CD6B00131F8F /* DataFormat.h */,
 				0FC712DC17CD8778008CC93C /* DeferredCompilationCallback.cpp */,
 				0FC712DD17CD8778008CC93C /* DeferredCompilationCallback.h */,
+				FE5068661AE25E280009DAB7 /* DeferredSourceDump.cpp */,
+				FE5068641AE246390009DAB7 /* DeferredSourceDump.h */,
 				0FBC0AE41496C7C100D4FBDD /* DFGExitProfile.cpp */,
 				0FBC0AE51496C7C100D4FBDD /* DFGExitProfile.h */,
 				969A07920ED1D3AE00F1F681 /* EvalCodeCache.h */,
@@ -5331,8 +5340,6 @@
 				0FF60AC016740F8100029779 /* ReduceWhitespace.h */,
 				1429D8830ED21C3D00B89619 /* SamplingTool.cpp */,
 				1429D8840ED21C3D00B89619 /* SamplingTool.h */,
-				FE5068661AE25E280009DAB7 /* DeferredSourceDump.cpp */,
-				FE5068641AE246390009DAB7 /* DeferredSourceDump.h */,
 				0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */,
 				0F5541B01613C1FB00CE3E25 /* SpecialPointer.h */,
 				0FD82E84141F3FDA00179C94 /* SpeculatedType.cpp */,
@@ -5345,6 +5352,8 @@
 				BCCF0D070EF0AAB900413C8F /* StructureStubInfo.h */,
 				0F2D4DE519832DAC007D4B19 /* ToThisStatus.cpp */,
 				0F2D4DE619832DAC007D4B19 /* ToThisStatus.h */,
+				0F952ABA1B487A7700C367C5 /* TrackedReferences.cpp */,
+				0F952ABB1B487A7700C367C5 /* TrackedReferences.h */,
 				0F2D4DE719832DAC007D4B19 /* TypeLocation.h */,
 				A79E781E15EECBA80047C855 /* UnlinkedCodeBlock.cpp */,
 				A79E781F15EECBA80047C855 /* UnlinkedCodeBlock.h */,
@@ -6060,6 +6069,7 @@
 				A5840E29187CA5E600843B10 /* inline-and-minify-stylesheets-and-scripts.py in Headers */,
 				0F24E55617F0B71C00ABB217 /* InlineCallFrameSet.h in Headers */,
 				99E45A2718A1B2590026D88F /* InputCursor.h in Headers */,
+				0F952ABD1B487A7700C367C5 /* TrackedReferences.h in Headers */,
 				A593CF7F1840362C00BFCE27 /* InspectorAgentBase.h in Headers */,
 				0F3E01AB19D353A500F61B7F /* DFGPrePostNumbering.h in Headers */,
 				A593CF87184038CA00BFCE27 /* InspectorAgentRegistry.h in Headers */,
@@ -7480,6 +7490,7 @@
 				655EB29B10CE2581001A990E /* NodesCodegen.cpp in Sources */,
 				6546F5211A32B313006F07D5 /* NullGetterFunction.cpp in Sources */,
 				65525FC51A6DD801007B5495 /* NullSetterFunction.cpp in Sources */,
+				0F1725FF1B48719A00AC3A55 /* DFGMinifiedGraph.cpp in Sources */,
 				14469DE2107EC7E700650446 /* NumberConstructor.cpp in Sources */,
 				14469DE3107EC7E700650446 /* NumberObject.cpp in Sources */,
 				14469DE4107EC7E700650446 /* NumberPrototype.cpp in Sources */,
@@ -7555,6 +7566,7 @@
 				A54CF2F5184EAB2400237F19 /* ScriptValue.cpp in Sources */,
 				A7299DA517D12858005F5FF9 /* SetConstructor.cpp in Sources */,
 				0FD1202F1A8AED12000F5280 /* FTLJSCallBase.cpp in Sources */,
+				0F952ABC1B487A7700C367C5 /* TrackedReferences.cpp in Sources */,
 				A790DD6D182F499700588807 /* SetIteratorPrototype.cpp in Sources */,
 				A7299DA117D12848005F5FF9 /* SetPrototype.cpp in Sources */,
 				0F2B670417B6B5AB00A7AE3F /* SimpleTypedArrayController.cpp in Sources */,

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -2801,6 +2801,13 @@
 
 #if ENABLE(DFG_JIT)
     if (JITCode::isOptimizingJIT(jitType())) {
+        // FIXME: This is an antipattern for two reasons. References introduced by the DFG
+        // that aren't in the original CodeBlock being compiled should be weakly referenced.
+        // Inline call frames aren't in the original CodeBlock, so they qualify as weak. Also,
+        // those weak references should already be tracked in the DFG as weak FrozenValues. So,
+        // there is probably no need for this. We already have assertions that this should be
+        // unnecessary.
+        // https://bugs.webkit.org/show_bug.cgi?id=146613
         DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
         if (dfgCommon->inlineCallFrames.get())
             dfgCommon->inlineCallFrames->visitAggregate(visitor);

Modified: trunk/Source/_javascript_Core/bytecode/CodeOrigin.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/bytecode/CodeOrigin.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/bytecode/CodeOrigin.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -150,6 +150,15 @@
 
 void InlineCallFrame::visitAggregate(SlotVisitor& visitor)
 {
+    // FIXME: This is an antipattern for two reasons. References introduced by the DFG
+    // that aren't in the original CodeBlock being compiled should be weakly referenced.
+    // Inline call frames aren't in the original CodeBlock, so they qualify as weak. Also,
+    // those weak references should already be tracked in the DFG as weak FrozenValues. So,
+    // there is probably no need for this. We already have assertions that this should be
+    // unnecessary. Finally, just marking the executable and not anything else in the inline
+    // call frame is almost certainly insufficient for what this method thought it was going
+    // to accomplish.
+    // https://bugs.webkit.org/show_bug.cgi?id=146613
     visitor.append(&executable);
 }
 

Modified: trunk/Source/_javascript_Core/bytecode/Operands.h (186690 => 186691)


--- trunk/Source/_javascript_Core/bytecode/Operands.h	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/bytecode/Operands.h	2015-07-10 21:19:51 UTC (rev 186691)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013, 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
@@ -149,6 +149,7 @@
     }
 
     const T& operand(int operand) const { return const_cast<const T&>(const_cast<Operands*>(this)->operand(operand)); }
+    const T& operand(VirtualRegister operand) const { return const_cast<const T&>(const_cast<Operands*>(this)->operand(operand)); }
     
     bool hasOperand(int operand) const
     {

Modified: trunk/Source/_javascript_Core/bytecode/StructureSet.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/bytecode/StructureSet.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/bytecode/StructureSet.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -27,6 +27,7 @@
 #include "StructureSet.h"
 
 #include "DFGAbstractValue.h"
+#include "TrackedReferences.h"
 #include <wtf/CommaPrinter.h>
 
 namespace JSC {
@@ -96,5 +97,13 @@
     dumpInContext(out, nullptr);
 }
 
+void StructureSet::validateReferences(const TrackedReferences& trackedReferences) const
+{
+    forEach(
+        [&] (Structure* structure) {
+            trackedReferences.check(structure);
+        });
+}
+
 } // namespace JSC
 

Modified: trunk/Source/_javascript_Core/bytecode/StructureSet.h (186690 => 186691)


--- trunk/Source/_javascript_Core/bytecode/StructureSet.h	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/bytecode/StructureSet.h	2015-07-10 21:19:51 UTC (rev 186691)
@@ -27,13 +27,15 @@
 #define StructureSet_h
 
 #include "ArrayProfile.h"
+#include "DumpContext.h"
 #include "SpeculatedType.h"
 #include "Structure.h"
-#include "DumpContext.h"
 #include <wtf/TinyPtrSet.h>
 
 namespace JSC {
 
+class TrackedReferences;
+
 namespace DFG {
 class StructureAbstractValue;
 struct AbstractValue;
@@ -77,6 +79,8 @@
     
     void dumpInContext(PrintStream&, DumpContext*) const;
     void dump(PrintStream&) const;
+    
+    void validateReferences(const TrackedReferences&) const;
 };
 
 } // namespace JSC

Added: trunk/Source/_javascript_Core/bytecode/TrackedReferences.cpp (0 => 186691)


--- trunk/Source/_javascript_Core/bytecode/TrackedReferences.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/bytecode/TrackedReferences.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -0,0 +1,81 @@
+/*
+ * 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. 
+ */
+
+#include "config.h"
+#include "TrackedReferences.h"
+
+#include "JSCInlines.h"
+#include <wtf/CommaPrinter.h>
+
+namespace JSC {
+
+TrackedReferences::TrackedReferences()
+{
+}
+
+TrackedReferences::~TrackedReferences()
+{
+}
+
+void TrackedReferences::add(JSCell* cell)
+{
+    if (cell)
+        m_references.add(cell);
+}
+
+void TrackedReferences::add(JSValue value)
+{
+    if (value.isCell())
+        add(value.asCell());
+}
+
+void TrackedReferences::check(JSCell* cell) const
+{
+    if (!cell)
+        return;
+    
+    if (m_references.contains(cell))
+        return;
+    
+    dataLog("Found untracked reference: ", RawPointer(cell), "\n");
+    dataLog("All tracked references: ", *this, "\n");
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+void TrackedReferences::check(JSValue value) const
+{
+    if (value.isCell())
+        check(value.asCell());
+}
+
+void TrackedReferences::dump(PrintStream& out) const
+{
+    CommaPrinter comma;
+    for (JSCell* cell : m_references)
+        out.print(comma, RawPointer(cell));
+}
+
+} // namespace JSC
+

Added: trunk/Source/_javascript_Core/bytecode/TrackedReferences.h (0 => 186691)


--- trunk/Source/_javascript_Core/bytecode/TrackedReferences.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/bytecode/TrackedReferences.h	2015-07-10 21:19:51 UTC (rev 186691)
@@ -0,0 +1,56 @@
+/*
+ * 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 TrackedReferences_h
+#define TrackedReferences_h
+
+#include "JSCJSValue.h"
+#include "JSCell.h"
+#include <wtf/HashSet.h>
+#include <wtf/PrintStream.h>
+
+namespace JSC {
+
+class TrackedReferences {
+public:
+    TrackedReferences();
+    ~TrackedReferences();
+    
+    void add(JSCell*);
+    void add(JSValue);
+    
+    void check(JSCell*) const;
+    void check(JSValue) const;
+    
+    void dump(PrintStream&) const;
+    
+private:
+    HashSet<JSCell*> m_references;
+};
+
+} // namespace JSC
+
+#endif // TrackedReferences_h
+

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractValue.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractValue.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractValue.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-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
@@ -30,6 +30,7 @@
 
 #include "DFGGraph.h"
 #include "JSCInlines.h"
+#include "TrackedReferences.h"
 
 namespace JSC { namespace DFG {
 
@@ -47,24 +48,6 @@
     checkConsistency();
 }
 
-void AbstractValue::setOSREntryValue(Graph& graph, const FrozenValue& value)
-{
-    if (!!value && value.value().isCell()) {
-        Structure* structure = value.structure();
-        m_structure = structure;
-        m_arrayModes = asArrayModes(structure->indexingType());
-    } else {
-        m_structure.clear();
-        m_arrayModes = 0;
-    }
-        
-    m_type = speculationFromValue(value.value());
-    m_value = value.value();
-        
-    checkConsistency();
-    assertIsRegistered(graph);
-}
-
 void AbstractValue::set(Graph& graph, const FrozenValue& value, StructureClobberState clobberState)
 {
     if (!!value && value.value().isCell()) {
@@ -172,6 +155,40 @@
     fixTypeForRepresentation(graph, node->result(), node);
 }
 
+bool AbstractValue::mergeOSREntryValue(Graph& graph, JSValue value)
+{
+    AbstractValue oldMe = *this;
+    
+    if (isClear()) {
+        FrozenValue* frozenValue = graph.freeze(value);
+        if (frozenValue->pointsToHeap()) {
+            m_structure = frozenValue->structure();
+            m_arrayModes = asArrayModes(frozenValue->structure()->indexingType());
+        } else {
+            m_structure.clear();
+            m_arrayModes = 0;
+        }
+        
+        m_type = speculationFromValue(value);
+        m_value = value;
+    } else {
+        mergeSpeculation(m_type, speculationFromValue(value));
+        if (!!value && value.isCell()) {
+            Structure* structure = value.asCell()->structure();
+            graph.registerStructure(structure);
+            mergeArrayModes(m_arrayModes, asArrayModes(structure->indexingType()));
+            m_structure.merge(StructureSet(structure));
+        }
+        if (m_value != value)
+            m_value = JSValue();
+    }
+    
+    checkConsistency();
+    assertIsRegistered(graph);
+    
+    return oldMe != *this;
+}
+
 FiltrationResult AbstractValue::filter(Graph& graph, const StructureSet& other)
 {
     if (isClear())
@@ -424,6 +441,12 @@
     out.print(")");
 }
 
+void AbstractValue::validateReferences(const TrackedReferences& trackedReferences)
+{
+    trackedReferences.check(m_value);
+    m_structure.validateReferences(trackedReferences);
+}
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractValue.h (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractValue.h	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractValue.h	2015-07-10 21:19:51 UTC (rev 186691)
@@ -39,8 +39,12 @@
 #include "DumpContext.h"
 #include "StructureSet.h"
 
-namespace JSC { namespace DFG {
+namespace JSC {
 
+class TrackedReferences;
+
+namespace DFG {
+
 class Graph;
 struct Node;
 
@@ -193,8 +197,6 @@
         return result;
     }
     
-    void setOSREntryValue(Graph&, const FrozenValue&);
-    
     void set(Graph&, const FrozenValue&, StructureClobberState);
     void set(Graph&, Structure*);
     void set(Graph&, const StructureSet&);
@@ -254,6 +256,8 @@
         return result;
     }
     
+    bool mergeOSREntryValue(Graph&, JSValue);
+    
     void merge(SpeculatedType type)
     {
         mergeSpeculation(m_type, type);
@@ -330,6 +334,8 @@
     void dumpInContext(PrintStream&, DumpContext*) const;
     void dump(PrintStream&) const;
     
+    void validateReferences(const TrackedReferences&);
+    
     // This is a proven constraint on the structures that this value can have right
     // now. The structure of the current value must belong to this set. The set may
     // be TOP, indicating that it is the set of all possible structures, in which

Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -4022,6 +4022,7 @@
         ASSERT(callsiteBlockHead);
         
         m_inlineCallFrame = byteCodeParser->m_graph.m_plan.inlineCallFrames->add();
+        byteCodeParser->m_graph.freeze(codeBlock->ownerExecutable());
         initializeLazyWriteBarrierForInlineCallFrameExecutable(
             byteCodeParser->m_graph.m_plan.writeBarriers,
             m_inlineCallFrame->executable,

Modified: trunk/Source/_javascript_Core/dfg/DFGCFAPhase.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGCFAPhase.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGCFAPhase.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-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
@@ -80,12 +80,52 @@
         } while (m_changed);
         
         if (m_graph.m_form != SSA) {
+            ASSERT(!m_changed);
+            
+            // Widen the abstract values at the block that serves as the must-handle OSR entry.
+            for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+                BasicBlock* block = m_graph.block(blockIndex);
+                if (!block)
+                    continue;
+                
+                if (!block->isOSRTarget)
+                    continue;
+                if (block->bytecodeBegin != m_graph.m_plan.osrEntryBytecodeIndex)
+                    continue;
+                
+                bool changed = false;
+                for (size_t i = m_graph.m_plan.mustHandleValues.size(); i--;) {
+                    int operand = m_graph.m_plan.mustHandleValues.operandForIndex(i);
+                    JSValue value = m_graph.m_plan.mustHandleValues[i];
+                    Node* node = block->variablesAtHead.operand(operand);
+                    if (!node)
+                        continue;
+                    
+                    AbstractValue& target = block->valuesAtHead.operand(operand);
+                    changed |= target.mergeOSREntryValue(m_graph, value);
+                    target.fixTypeForRepresentation(
+                        m_graph, resultFor(node->variableAccessData()->flushFormat()));
+                }
+                
+                if (changed) {
+                    m_changed = true;
+                    block->cfaShouldRevisit = true;
+                }
+            }
+
+            // Propagate any of the changes we just introduced.
+            while (m_changed) {
+                m_changed = false;
+                performForwardCFA();
+            }
+            
             // Make sure we record the intersection of all proofs that we ever allowed the
             // compiler to rely upon.
             for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
                 BasicBlock* block = m_graph.block(blockIndex);
                 if (!block)
                     continue;
+                
                 block->intersectionOfCFAHasVisited &= block->cfaHasVisited;
                 for (unsigned i = block->intersectionOfPastValuesAtHead.size(); i--;)
                     block->intersectionOfPastValuesAtHead[i].filter(block->valuesAtHead[i]);

Modified: trunk/Source/_javascript_Core/dfg/DFGCommonData.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGCommonData.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGCommonData.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 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
@@ -32,6 +32,7 @@
 #include "DFGNode.h"
 #include "DFGPlan.h"
 #include "JSCInlines.h"
+#include "TrackedReferences.h"
 #include "VM.h"
 
 namespace JSC { namespace DFG {
@@ -72,6 +73,24 @@
     return true;
 }
 
+void CommonData::validateReferences(const TrackedReferences& trackedReferences)
+{
+    if (InlineCallFrameSet* set = inlineCallFrames.get()) {
+        for (InlineCallFrame* inlineCallFrame : *set) {
+            for (ValueRecovery& recovery : inlineCallFrame->arguments) {
+                if (recovery.isConstant())
+                    trackedReferences.check(recovery.constant());
+            }
+            
+            if (ScriptExecutable* executable = inlineCallFrame->executable.get())
+                trackedReferences.check(executable);
+            
+            if (inlineCallFrame->calleeRecovery.isConstant())
+                trackedReferences.check(inlineCallFrame->calleeRecovery.constant());
+        }
+    }
+}
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)

Modified: trunk/Source/_javascript_Core/dfg/DFGCommonData.h (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGCommonData.h	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGCommonData.h	2015-07-10 21:19:51 UTC (rev 186691)
@@ -41,6 +41,7 @@
 
 class CodeBlock;
 class Identifier;
+class TrackedReferences;
 
 namespace DFG {
 
@@ -86,6 +87,8 @@
     {
         return std::max(frameRegisterCount, requiredRegisterCountForExit);
     }
+    
+    void validateReferences(const TrackedReferences&);
 
     RefPtr<InlineCallFrameSet> inlineCallFrames;
     Vector<CodeOrigin, 0, UnsafeVectorOverflow> codeOrigins;

Modified: trunk/Source/_javascript_Core/dfg/DFGFrozenValue.h (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGFrozenValue.h	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGFrozenValue.h	2015-07-10 21:19:51 UTC (rev 186691)
@@ -41,14 +41,14 @@
 public:
     FrozenValue()
         : m_structure(nullptr)
-        , m_strength(FragileValue)
+        , m_strength(WeakValue)
     {
     }
     
     FrozenValue(JSValue value)
         : m_value(value)
         , m_structure(nullptr)
-        , m_strength(FragileValue)
+        , m_strength(WeakValue)
     {
         RELEASE_ASSERT(!value || !value.isCell());
     }
@@ -60,7 +60,7 @@
     {
         ASSERT((!!value && value.isCell()) == !!structure);
         ASSERT(!value || !value.isCell() || value.asCell()->classInfo() == structure->classInfo());
-        ASSERT(!!structure || (strength == FragileValue));
+        ASSERT(!!structure || (strength == WeakValue));
     }
     
     static FrozenValue* emptySingleton();
@@ -89,12 +89,9 @@
             m_strength = merge(m_strength, strength);
     }
     
-    // The strength of the value itself. The structure should be viewed as fragile
-    // except if it is watched, in which case it's weak. Note that currently we
-    // watch all watchable structures indiscriminantly, and so we also mark them
-    // weakly. We could improve on this: any optimization that makes use of a
-    // structure could signal that it has done so, and we could avoid watching
-    // watchable structures that we had never marked in such a way.
+    bool pointsToHeap() const { return !!value() && value().isCell(); }
+    
+    // The strength of the value itself. The structure is almost always weak.
     ValueStrength strength() const { return m_strength; }
     
     void dumpInContext(PrintStream& out, DumpContext* context) const;
@@ -116,7 +113,7 @@
         return FrozenValue(
             value,
             (!!value && value.isCell()) ? value.asCell()->structure() : nullptr,
-            FragileValue);
+            WeakValue);
     }
 
     JSValue m_value;

Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -62,7 +62,6 @@
     , m_codeBlock(m_plan.codeBlock.get())
     , m_profiledBlock(m_codeBlock->alternative())
     , m_allocator(longLivedState.m_allocator)
-    , m_mustHandleValues(OperandsLike, plan.mustHandleValues)
     , m_nextMachineLocal(0)
     , m_fixpointState(BeforeFixpoint)
     , m_structureRegistrationState(HaveNotStartedRegistering)
@@ -72,9 +71,6 @@
 {
     ASSERT(m_profiledBlock);
     
-    for (unsigned i = m_mustHandleValues.size(); i--;)
-        m_mustHandleValues[i] = freezeFragile(plan.mustHandleValues[i]);
-
     m_hasDebuggerEnabled = m_profiledBlock->globalObject()->hasDebugger()
         || Options::forceDebuggerBytecodeGeneration();
 }
@@ -529,6 +525,12 @@
         out.print("\n");
     }
     
+    out.print("GC Values:\n");
+    for (FrozenValue* value : m_frozenValues) {
+        if (value->pointsToHeap())
+            out.print("    ", inContext(*value, &myContext), "\n");
+    }
+    
     if (!myContext.isEmpty()) {
         myContext.dump(out);
         out.print("\n");
@@ -1106,13 +1108,13 @@
     m_codeBlock->constants().resize(0);
     m_codeBlock->constantsSourceCodeRepresentation().resize(0);
     for (FrozenValue* value : m_frozenValues) {
-        if (value->structure())
-            ASSERT(m_plan.weakReferences.contains(value->structure()));
+        if (!value->pointsToHeap())
+            continue;
         
+        ASSERT(value->structure());
+        ASSERT(m_plan.weakReferences.contains(value->structure()));
+        
         switch (value->strength()) {
-        case FragileValue: {
-            break;
-        }
         case WeakValue: {
             m_plan.weakReferences.addLazily(value->value().asCell());
             break;
@@ -1202,7 +1204,7 @@
     }
 }
 
-FrozenValue* Graph::freezeFragile(JSValue value)
+FrozenValue* Graph::freeze(JSValue value)
 {
     if (UNLIKELY(!value))
         return FrozenValue::emptySingleton();
@@ -1221,16 +1223,9 @@
     return result.iterator->value = m_frozenValues.add(frozenValue);
 }
 
-FrozenValue* Graph::freeze(JSValue value)
-{
-    FrozenValue* result = freezeFragile(value);
-    result->strengthenTo(WeakValue);
-    return result;
-}
-
 FrozenValue* Graph::freezeStrong(JSValue value)
 {
-    FrozenValue* result = freezeFragile(value);
+    FrozenValue* result = freeze(value);
     result->strengthenTo(StrongValue);
     return result;
 }

Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.h (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGGraph.h	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.h	2015-07-10 21:19:51 UTC (rev 186691)
@@ -186,9 +186,8 @@
 
     void dethread();
     
-    FrozenValue* freezeFragile(JSValue value);
-    FrozenValue* freeze(JSValue value); // We use weak freezing by default. Shorthand for freezeFragile(value)->strengthenTo(WeakValue);
-    FrozenValue* freezeStrong(JSValue value); // Shorthand for freezeFragile(value)->strengthenTo(StrongValue).
+    FrozenValue* freeze(JSValue); // We use weak freezing by default.
+    FrozenValue* freezeStrong(JSValue); // Shorthand for freeze(value)->strengthenTo(StrongValue).
     
     void convertToConstant(Node* node, FrozenValue* value);
     void convertToConstant(Node* node, JSValue value);
@@ -800,8 +799,6 @@
     
     NodeAllocator& m_allocator;
 
-    Operands<FrozenValue*> m_mustHandleValues;
-    
     Vector< RefPtr<BasicBlock> , 8> m_blocks;
     Vector<Edge, 16> m_varArgChildren;
 

Modified: trunk/Source/_javascript_Core/dfg/DFGInPlaceAbstractState.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGInPlaceAbstractState.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGInPlaceAbstractState.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -150,26 +150,6 @@
             block->valuesAtHead.local(i).clear();
             block->valuesAtTail.local(i).clear();
         }
-        if (m_graph.m_form == SSA)
-            continue;
-        if (!block->isOSRTarget)
-            continue;
-        if (block->bytecodeBegin != m_graph.m_plan.osrEntryBytecodeIndex)
-            continue;
-        for (size_t i = 0; i < m_graph.m_mustHandleValues.size(); ++i) {
-            int operand = m_graph.m_mustHandleValues.operandForIndex(i);
-            Node* node = block->variablesAtHead.operand(operand);
-            if (!node)
-                continue;
-            AbstractValue source;
-            source.setOSREntryValue(m_graph, *m_graph.m_mustHandleValues[i]);
-            AbstractValue& target = block->valuesAtHead.operand(operand);
-            VariableAccessData* variable = node->variableAccessData();
-            FlushFormat format = variable->flushFormat();
-            target.merge(source);
-            target.fixTypeForRepresentation(m_graph, resultFor(format));
-        }
-        block->cfaShouldRevisit = true;
     }
     if (m_graph.m_form == SSA) {
         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCode.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGJITCode.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCode.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -30,6 +30,7 @@
 
 #include "CodeBlock.h"
 #include "JSCInlines.h"
+#include "TrackedReferences.h"
 
 namespace JSC { namespace DFG {
 
@@ -170,6 +171,18 @@
 }
 #endif // ENABLE(FTL_JIT)
 
+void JITCode::validateReferences(const TrackedReferences& trackedReferences)
+{
+    common.validateReferences(trackedReferences);
+    
+    for (OSREntryData& entry : osrEntry) {
+        for (unsigned i = entry.m_expectedValues.size(); i--;)
+            entry.m_expectedValues[i].validateReferences(trackedReferences);
+    }
+    
+    minifiedDFG.validateReferences(trackedReferences);
+}
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCode.h (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGJITCode.h	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCode.h	2015-07-10 21:19:51 UTC (rev 186691)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-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
@@ -38,8 +38,12 @@
 #include "JITCode.h"
 #include <wtf/SegmentedVector.h>
 
-namespace JSC { namespace DFG {
+namespace JSC {
 
+class TrackedReferences;
+
+namespace DFG {
+
 class JITCompiler;
 
 class JITCode : public DirectJITCode {
@@ -107,6 +111,8 @@
     void setOptimizationThresholdBasedOnCompilationResult(CodeBlock*, CompilationResult);
 #endif // ENABLE(FTL_JIT)
     
+    void validateReferences(const TrackedReferences&) override;
+    
     void shrinkToFit();
     
 private:

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -475,6 +475,54 @@
 }
 #endif
 
+void JITCompiler::noticeOSREntry(BasicBlock& basicBlock, JITCompiler::Label blockHead, LinkBuffer& linkBuffer)
+{
+    // OSR entry is not allowed into blocks deemed unreachable by control flow analysis.
+    if (!basicBlock.intersectionOfCFAHasVisited)
+        return;
+        
+    OSREntryData* entry = m_jitCode->appendOSREntryData(basicBlock.bytecodeBegin, linkBuffer.offsetOf(blockHead));
+    
+    entry->m_expectedValues = basicBlock.intersectionOfPastValuesAtHead;
+        
+    // Fix the expected values: in our protocol, a dead variable will have an expected
+    // value of (None, []). But the old JIT may stash some values there. So we really
+    // need (Top, TOP).
+    for (size_t argument = 0; argument < basicBlock.variablesAtHead.numberOfArguments(); ++argument) {
+        Node* node = basicBlock.variablesAtHead.argument(argument);
+        if (!node || !node->shouldGenerate())
+            entry->m_expectedValues.argument(argument).makeHeapTop();
+    }
+    for (size_t local = 0; local < basicBlock.variablesAtHead.numberOfLocals(); ++local) {
+        Node* node = basicBlock.variablesAtHead.local(local);
+        if (!node || !node->shouldGenerate())
+            entry->m_expectedValues.local(local).makeHeapTop();
+        else {
+            VariableAccessData* variable = node->variableAccessData();
+            entry->m_machineStackUsed.set(variable->machineLocal().toLocal());
+                
+            switch (variable->flushFormat()) {
+            case FlushedDouble:
+                entry->m_localsForcedDouble.set(local);
+                break;
+            case FlushedInt52:
+                entry->m_localsForcedMachineInt.set(local);
+                break;
+            default:
+                break;
+            }
+            
+            if (variable->local() != variable->machineLocal()) {
+                entry->m_reshufflings.append(
+                    OSREntryReshuffling(
+                        variable->local().offset(), variable->machineLocal().offset()));
+            }
+        }
+    }
+        
+    entry->m_reshufflings.shrinkToFit();
+}
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.h (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.h	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.h	2015-07-10 21:19:51 UTC (rev 186691)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013-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
@@ -265,53 +265,7 @@
 #endif
     }
 
-    void noticeOSREntry(BasicBlock& basicBlock, JITCompiler::Label blockHead, LinkBuffer& linkBuffer)
-    {
-        // OSR entry is not allowed into blocks deemed unreachable by control flow analysis.
-        if (!basicBlock.intersectionOfCFAHasVisited)
-            return;
-        
-        OSREntryData* entry = m_jitCode->appendOSREntryData(basicBlock.bytecodeBegin, linkBuffer.offsetOf(blockHead));
-        
-        entry->m_expectedValues = basicBlock.intersectionOfPastValuesAtHead;
-        
-        // Fix the expected values: in our protocol, a dead variable will have an expected
-        // value of (None, []). But the old JIT may stash some values there. So we really
-        // need (Top, TOP).
-        for (size_t argument = 0; argument < basicBlock.variablesAtHead.numberOfArguments(); ++argument) {
-            Node* node = basicBlock.variablesAtHead.argument(argument);
-            if (!node || !node->shouldGenerate())
-                entry->m_expectedValues.argument(argument).makeHeapTop();
-        }
-        for (size_t local = 0; local < basicBlock.variablesAtHead.numberOfLocals(); ++local) {
-            Node* node = basicBlock.variablesAtHead.local(local);
-            if (!node || !node->shouldGenerate())
-                entry->m_expectedValues.local(local).makeHeapTop();
-            else {
-                VariableAccessData* variable = node->variableAccessData();
-                entry->m_machineStackUsed.set(variable->machineLocal().toLocal());
-                
-                switch (variable->flushFormat()) {
-                case FlushedDouble:
-                    entry->m_localsForcedDouble.set(local);
-                    break;
-                case FlushedInt52:
-                    entry->m_localsForcedMachineInt.set(local);
-                    break;
-                default:
-                    break;
-                }
-                
-                if (variable->local() != variable->machineLocal()) {
-                    entry->m_reshufflings.append(
-                        OSREntryReshuffling(
-                            variable->local().offset(), variable->machineLocal().offset()));
-                }
-            }
-        }
-        
-        entry->m_reshufflings.shrinkToFit();
-    }
+    void noticeOSREntry(BasicBlock&, JITCompiler::Label blockHead, LinkBuffer&);
     
     RefPtr<JITCode> jitCode() { return m_jitCode; }
     

Added: trunk/Source/_javascript_Core/dfg/DFGMinifiedGraph.cpp (0 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGMinifiedGraph.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/dfg/DFGMinifiedGraph.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -0,0 +1,53 @@
+/*
+ * 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. 
+ */
+
+#include "config.h"
+#include "DFGMinifiedGraph.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "JSCInlines.h"
+#include "TrackedReferences.h"
+
+namespace JSC { namespace DFG {
+
+void MinifiedGraph::prepareAndShrink()
+{
+    std::sort(m_list.begin(), m_list.end(), MinifiedNode::compareByNodeIndex);
+    m_list.shrinkToFit();
+}
+
+void MinifiedGraph::validateReferences(const TrackedReferences& trackedReferences)
+{
+    for (MinifiedNode& node : m_list) {
+        if (node.hasConstant())
+            trackedReferences.check(node.constant());
+    }
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+

Modified: trunk/Source/_javascript_Core/dfg/DFGMinifiedGraph.h (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGMinifiedGraph.h	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGMinifiedGraph.h	2015-07-10 21:19:51 UTC (rev 186691)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 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
@@ -33,8 +33,12 @@
 #include <wtf/StdLibExtras.h>
 #include <wtf/Vector.h>
 
-namespace JSC { namespace DFG {
+namespace JSC {
 
+class TrackedReferences;
+
+namespace DFG {
+
 class MinifiedGraph {
 public:
     MinifiedGraph() { }
@@ -50,12 +54,10 @@
         m_list.append(node);
     }
     
-    void prepareAndShrink()
-    {
-        std::sort(m_list.begin(), m_list.end(), MinifiedNode::compareByNodeIndex);
-        m_list.shrinkToFit();
-    }
+    void prepareAndShrink();
     
+    void validateReferences(const TrackedReferences&);
+    
 private:
     Vector<MinifiedNode> m_list;
 };

Modified: trunk/Source/_javascript_Core/dfg/DFGOSREntry.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGOSREntry.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGOSREntry.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013, 2014, 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
@@ -35,9 +35,61 @@
 #include "JIT.h"
 #include "JSStackInlines.h"
 #include "JSCInlines.h"
+#include <wtf/CommaPrinter.h>
 
 namespace JSC { namespace DFG {
 
+void OSREntryData::dumpInContext(PrintStream& out, DumpContext* context) const
+{
+    out.print("bc#", m_bytecodeIndex, ", machine code offset = ", m_machineCodeOffset);
+    out.print(", stack rules = [");
+    
+    auto printOperand = [&] (VirtualRegister reg) {
+        out.print(inContext(m_expectedValues.operand(reg), context), " (");
+        VirtualRegister toReg;
+        bool overwritten = false;
+        for (OSREntryReshuffling reshuffling : m_reshufflings) {
+            if (reg == VirtualRegister(reshuffling.fromOffset)) {
+                toReg = VirtualRegister(reshuffling.toOffset);
+                break;
+            }
+            if (reg == VirtualRegister(reshuffling.toOffset))
+                overwritten = true;
+        }
+        if (!overwritten && !toReg.isValid())
+            toReg = reg;
+        if (toReg.isValid()) {
+            if (toReg.isLocal() && !m_machineStackUsed.get(toReg.toLocal()))
+                out.print("ignored");
+            else
+                out.print("maps to ", toReg);
+        } else
+            out.print("overwritten");
+        if (reg.isLocal() && m_localsForcedDouble.get(reg.toLocal()))
+            out.print(", forced double");
+        if (reg.isLocal() && m_localsForcedMachineInt.get(reg.toLocal()))
+            out.print(", forced machine int");
+        out.print(")");
+    };
+    
+    CommaPrinter comma;
+    for (size_t argumentIndex = m_expectedValues.numberOfArguments(); argumentIndex--;) {
+        out.print(comma, "arg", argumentIndex, ":");
+        printOperand(virtualRegisterForArgument(argumentIndex));
+    }
+    for (size_t localIndex = 0; localIndex < m_expectedValues.numberOfLocals(); ++localIndex) {
+        out.print(comma, "loc", localIndex, ":");
+        printOperand(virtualRegisterForLocal(localIndex));
+    }
+    
+    out.print("], machine stack used = ", m_machineStackUsed);
+}
+
+void OSREntryData::dump(PrintStream& out) const
+{
+    dumpInContext(out, nullptr);
+}
+
 void* prepareOSREntry(ExecState* exec, CodeBlock* codeBlock, unsigned bytecodeIndex)
 {
     ASSERT(JITCode::isOptimizingJIT(codeBlock->jitType()));

Modified: trunk/Source/_javascript_Core/dfg/DFGOSREntry.h (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGOSREntry.h	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGOSREntry.h	2015-07-10 21:19:51 UTC (rev 186691)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013, 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
@@ -60,6 +60,9 @@
     BitVector m_localsForcedMachineInt;
     Vector<OSREntryReshuffling> m_reshufflings;
     BitVector m_machineStackUsed;
+    
+    void dumpInContext(PrintStream&, DumpContext*) const;
+    void dump(PrintStream&) const;
 };
 
 inline unsigned getOSREntryDataBytecodeIndex(OSREntryData* osrEntryData)

Modified: trunk/Source/_javascript_Core/dfg/DFGPlan.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGPlan.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGPlan.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -76,6 +76,7 @@
 #include "JSCInlines.h"
 #include "OperandsInlines.h"
 #include "ProfilerDatabase.h"
+#include "TrackedReferences.h"
 #include <wtf/CurrentTime.h>
 
 #if ENABLE(FTL_JIT)
@@ -536,6 +537,21 @@
     
     reallyAdd(codeBlock->jitCode()->dfgCommon());
     
+    if (validationEnabled()) {
+        TrackedReferences trackedReferences;
+        
+        for (WriteBarrier<JSCell>& reference : codeBlock->jitCode()->dfgCommon()->weakReferences)
+            trackedReferences.add(reference.get());
+        for (WriteBarrier<Structure>& reference : codeBlock->jitCode()->dfgCommon()->weakStructureReferences)
+            trackedReferences.add(reference.get());
+        for (WriteBarrier<Unknown>& constant : codeBlock->constants())
+            trackedReferences.add(constant.get());
+        
+        // Check that any other references that we have anywhere in the JITCode are also
+        // tracked either strongly or weakly.
+        codeBlock->jitCode()->validateReferences(trackedReferences);
+    }
+    
     return CompilationSuccessful;
 }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -1631,6 +1631,15 @@
         m_jit.noticeOSREntry(*block, m_osrEntryHeads[osrEntryIndex++], linkBuffer);
     }
     ASSERT(osrEntryIndex == m_osrEntryHeads.size());
+    
+    if (verboseCompilationEnabled()) {
+        DumpContext dumpContext;
+        dataLog("OSR Entries:\n");
+        for (OSREntryData& entryData : m_jit.jitCode()->osrEntry)
+            dataLog("    ", inContext(entryData, &dumpContext), "\n");
+        if (!dumpContext.isEmpty())
+            dumpContext.dump(WTF::dataFile());
+    }
 }
 
 void SpeculativeJIT::compileDoublePutByVal(Node* node, SpeculateCellOperand& base, SpeculateStrictInt32Operand& property)

Modified: trunk/Source/_javascript_Core/dfg/DFGStructureAbstractValue.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGStructureAbstractValue.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGStructureAbstractValue.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -386,6 +386,13 @@
     dumpInContext(out, 0);
 }
 
+void StructureAbstractValue::validateReferences(const TrackedReferences& trackedReferences) const
+{
+    if (isTop())
+        return;
+    m_set.validateReferences(trackedReferences);
+}
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)

Modified: trunk/Source/_javascript_Core/dfg/DFGStructureAbstractValue.h (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGStructureAbstractValue.h	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGStructureAbstractValue.h	2015-07-10 21:19:51 UTC (rev 186691)
@@ -34,8 +34,12 @@
 #include "DumpContext.h"
 #include "StructureSet.h"
 
-namespace JSC { namespace DFG {
+namespace JSC {
 
+class TrackedReferences;
+
+namespace DFG {
+
 class StructureAbstractValue {
 public:
     StructureAbstractValue() { }
@@ -214,6 +218,8 @@
     bool overlaps(const StructureSet& other) const;
     bool overlaps(const StructureAbstractValue& other) const;
     
+    void validateReferences(const TrackedReferences&) const;
+    
 private:
     static const uintptr_t clobberedFlag = StructureSet::reservedFlag;
     static const uintptr_t topValue = StructureSet::reservedValue;

Modified: trunk/Source/_javascript_Core/dfg/DFGValidate.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGValidate.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGValidate.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -252,6 +252,10 @@
                         VALIDATE((node), !variant.oldStructureForTransition()->dfgShouldWatch());
                     }
                     break;
+                case DoubleConstant:
+                case Int52Constant:
+                    VALIDATE((node), node->isNumberConstant());
+                    break;
                 default:
                     break;
                 }

Modified: trunk/Source/_javascript_Core/dfg/DFGValueStrength.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGValueStrength.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGValueStrength.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 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
@@ -35,9 +35,6 @@
 void printInternal(PrintStream& out, ValueStrength strength)
 {
     switch (strength) {
-    case FragileValue:
-        out.print("Fragile");
-        return;
     case WeakValue:
         out.print("Weak");
         return;

Modified: trunk/Source/_javascript_Core/dfg/DFGValueStrength.h (186690 => 186691)


--- trunk/Source/_javascript_Core/dfg/DFGValueStrength.h	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/dfg/DFGValueStrength.h	2015-07-10 21:19:51 UTC (rev 186691)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 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
@@ -33,12 +33,6 @@
 namespace JSC { namespace DFG {
 
 enum ValueStrength {
-    // The value is known to the DFG but no optimizations have been performed that require the
-    // value to be kept alive. All OSR entry values are fragile until we do some optimization that
-    // uses them, like actually constant folding a variable to that value. By convention we say
-    // that all non-cells are fragile.
-    FragileValue,
-    
     // The value has been used for optimization and it arose through inference. We don't want the
     // fact that we optimized the code to result in the GC keeping this value alive unnecessarily,
     // so we'd rather kill the code and recompile than keep the object alive longer.
@@ -52,18 +46,14 @@
 inline ValueStrength merge(ValueStrength a, ValueStrength b)
 {
     switch (a) {
-    case FragileValue:
-        return b;
     case WeakValue:
-        if (b == StrongValue)
-            return StrongValue;
-        return WeakValue;
+        return b;
     case StrongValue:
         return StrongValue;
     }
     RELEASE_ASSERT_NOT_REACHED();
 
-    return FragileValue;
+    return WeakValue;
 }
 
 } } // namespace JSC::DFG

Modified: trunk/Source/_javascript_Core/ftl/FTLExitPropertyValue.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/ftl/FTLExitPropertyValue.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/ftl/FTLExitPropertyValue.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -40,6 +40,11 @@
     out.print(m_location, " => ", m_value);
 }
 
+void ExitPropertyValue::validateReferences(const TrackedReferences& trackedReferences) const
+{
+    m_value.validateReferences(trackedReferences);
+}
+
 } } // namespace JSC::FTL
 
 #endif // ENABLE(FTL_JIT)

Modified: trunk/Source/_javascript_Core/ftl/FTLExitPropertyValue.h (186690 => 186691)


--- trunk/Source/_javascript_Core/ftl/FTLExitPropertyValue.h	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/ftl/FTLExitPropertyValue.h	2015-07-10 21:19:51 UTC (rev 186691)
@@ -31,8 +31,12 @@
 #include "DFGPromotedHeapLocation.h"
 #include "FTLExitValue.h"
 
-namespace JSC { namespace FTL {
+namespace JSC {
 
+class TrackedReferences;
+
+namespace FTL {
+
 class ExitPropertyValue {
 public:
     ExitPropertyValue()
@@ -54,6 +58,8 @@
     ExitPropertyValue withLocalsOffset(int offset) const;
     
     void dump(PrintStream& out) const;
+    
+    void validateReferences(const TrackedReferences&) const;
 
 private:
     DFG::PromotedLocationDescriptor m_location;

Modified: trunk/Source/_javascript_Core/ftl/FTLExitTimeObjectMaterialization.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/ftl/FTLExitTimeObjectMaterialization.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/ftl/FTLExitTimeObjectMaterialization.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -70,6 +70,12 @@
     out.print(RawPointer(this), ":", Graph::opName(m_type), "(", listDump(m_properties), ")");
 }
 
+void ExitTimeObjectMaterialization::validateReferences(const TrackedReferences& trackedReferences) const
+{
+    for (ExitPropertyValue value : m_properties)
+        value.validateReferences(trackedReferences);
+}
+
 } } // namespace JSC::FTL
 
 #endif // ENABLE(FTL_JIT)

Modified: trunk/Source/_javascript_Core/ftl/FTLExitTimeObjectMaterialization.h (186690 => 186691)


--- trunk/Source/_javascript_Core/ftl/FTLExitTimeObjectMaterialization.h	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/ftl/FTLExitTimeObjectMaterialization.h	2015-07-10 21:19:51 UTC (rev 186691)
@@ -33,8 +33,12 @@
 #include "FTLExitValue.h"
 #include <wtf/Noncopyable.h>
 
-namespace JSC { namespace FTL {
+namespace JSC {
 
+class TrackedReferences;
+
+namespace FTL {
+
 class ExitTimeObjectMaterialization {
     WTF_MAKE_NONCOPYABLE(ExitTimeObjectMaterialization)
 public:
@@ -53,6 +57,8 @@
     
     void dump(PrintStream& out) const;
     
+    void validateReferences(const TrackedReferences&) const;
+    
 private:
     DFG::NodeType m_type;
     CodeOrigin m_origin;

Modified: trunk/Source/_javascript_Core/ftl/FTLExitValue.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/ftl/FTLExitValue.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/ftl/FTLExitValue.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -30,6 +30,7 @@
 
 #include "FTLExitTimeObjectMaterialization.h"
 #include "JSCInlines.h"
+#include "TrackedReferences.h"
 
 namespace JSC { namespace FTL {
 
@@ -126,6 +127,12 @@
     dumpInContext(out, 0);
 }
 
+void ExitValue::validateReferences(const TrackedReferences& trackedReferences) const
+{
+    if (isConstant())
+        trackedReferences.check(constant());
+}
+
 } } // namespace JSC::FTL
 
 #endif // ENABLE(FTL_JIT)

Modified: trunk/Source/_javascript_Core/ftl/FTLExitValue.h (186690 => 186691)


--- trunk/Source/_javascript_Core/ftl/FTLExitValue.h	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/ftl/FTLExitValue.h	2015-07-10 21:19:51 UTC (rev 186691)
@@ -34,8 +34,12 @@
 #include "VirtualRegister.h"
 #include <wtf/PrintStream.h>
 
-namespace JSC { namespace FTL {
+namespace JSC {
 
+class TrackedReferences;
+
+namespace FTL {
+
 // This is like ValueRecovery, but respects the way that the FTL does OSR
 // exit: the live non-constant non-flushed values are passed as arguments
 // to a noreturn tail call. ExitValue is hence mostly responsible for
@@ -222,6 +226,8 @@
     void dump(PrintStream&) const;
     void dumpInContext(PrintStream&, DumpContext*) const;
     
+    void validateReferences(const TrackedReferences&) const;
+    
 private:
     ExitValueKind m_kind;
     union {

Modified: trunk/Source/_javascript_Core/ftl/FTLJITCode.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/ftl/FTLJITCode.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/ftl/FTLJITCode.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 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
@@ -125,6 +125,14 @@
     return &common;
 }
 
+void JITCode::validateReferences(const TrackedReferences& trackedReferences)
+{
+    common.validateReferences(trackedReferences);
+    
+    for (OSRExit& exit : osrExit)
+        exit.validateReferences(trackedReferences);
+}
+
 } } // namespace JSC::FTL
 
 #endif // ENABLE(FTL_JIT)

Modified: trunk/Source/_javascript_Core/ftl/FTLJITCode.h (186690 => 186691)


--- trunk/Source/_javascript_Core/ftl/FTLJITCode.h	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/ftl/FTLJITCode.h	2015-07-10 21:19:51 UTC (rev 186691)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 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
@@ -47,8 +47,12 @@
 
 #define SECTION_NAME(NAME) (SECTION_NAME_PREFIX NAME)
 
-namespace JSC { namespace FTL {
+namespace JSC {
 
+class TrackedReferences;
+
+namespace FTL {
+
 class JITCode : public JSC::JITCode {
 public:
     JITCode();
@@ -67,6 +71,8 @@
     void initializeArityCheckEntrypoint(CodeRef);
     void initializeAddressForCall(CodePtr);
     
+    void validateReferences(const TrackedReferences&) override;
+    
     const Vector<RefPtr<ExecutableMemoryHandle>>& handles() const { return m_handles; }
     const Vector<RefPtr<DataSection>>& dataSections() const { return m_dataSections; }
     

Modified: trunk/Source/_javascript_Core/ftl/FTLOSRExit.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/ftl/FTLOSRExit.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/ftl/FTLOSRExit.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -61,6 +61,15 @@
         m_patchableCodeOffset);
 }
 
+void OSRExit::validateReferences(const TrackedReferences& trackedReferences)
+{
+    for (unsigned i = m_values.size(); i--;)
+        m_values[i].validateReferences(trackedReferences);
+    
+    for (ExitTimeObjectMaterialization* materialization : m_materializations)
+        materialization->validateReferences(trackedReferences);
+}
+
 } } // namespace JSC::FTL
 
 #endif // ENABLE(FTL_JIT)

Modified: trunk/Source/_javascript_Core/ftl/FTLOSRExit.h (186690 => 186691)


--- trunk/Source/_javascript_Core/ftl/FTLOSRExit.h	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/ftl/FTLOSRExit.h	2015-07-10 21:19:51 UTC (rev 186691)
@@ -41,8 +41,12 @@
 #include "ValueProfile.h"
 #include "VirtualRegister.h"
 
-namespace JSC { namespace FTL {
+namespace JSC {
 
+class TrackedReferences;
+
+namespace FTL {
+
 // Tracks one OSR exit site within the FTL JIT. OSR exit in FTL works by deconstructing
 // the crazy that is OSR down to simple SSA CFG primitives that any compiler backend
 // (including of course LLVM) can grok and do meaningful things to. An exit is just a
@@ -159,6 +163,8 @@
     {
         OSRExitBase::considerAddingAsFrequentExitSite(profiledCodeBlock, ExitFromFTL);
     }
+    
+    void validateReferences(const TrackedReferences&);
 };
 
 } } // namespace JSC::FTL

Modified: trunk/Source/_javascript_Core/jit/JITCode.cpp (186690 => 186691)


--- trunk/Source/_javascript_Core/jit/JITCode.cpp	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/jit/JITCode.cpp	2015-07-10 21:19:51 UTC (rev 186691)
@@ -64,6 +64,10 @@
     }
 }
 
+void JITCode::validateReferences(const TrackedReferences&)
+{
+}
+
 JSValue JITCode::execute(VM* vm, ProtoCallFrame* protoCallFrame)
 {
     void* entryAddress;

Modified: trunk/Source/_javascript_Core/jit/JITCode.h (186690 => 186691)


--- trunk/Source/_javascript_Core/jit/JITCode.h	2015-07-10 21:17:47 UTC (rev 186690)
+++ trunk/Source/_javascript_Core/jit/JITCode.h	2015-07-10 21:19:51 UTC (rev 186691)
@@ -46,6 +46,7 @@
 }
 
 struct ProtoCallFrame;
+class TrackedReferences;
 class VM;
 
 class JITCode : public ThreadSafeRefCounted<JITCode> {
@@ -183,6 +184,8 @@
     virtual FTL::JITCode* ftl();
     virtual FTL::ForOSREntryJITCode* ftlForOSREntry();
     
+    virtual void validateReferences(const TrackedReferences&);
+    
     JSValue execute(VM*, ProtoCallFrame*);
     
     void* start() { return dataAddressAtOffset(0); }

Added: trunk/Source/_javascript_Core/tests/stress/dead-osr-entry-value.js (0 => 186691)


--- trunk/Source/_javascript_Core/tests/stress/dead-osr-entry-value.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/dead-osr-entry-value.js	2015-07-10 21:19:51 UTC (rev 186691)
@@ -0,0 +1,16 @@
+function foo() {
+    var o = {f:42};
+    var result = 0;
+    OSRExit();
+    for (var i = 0; i < 10000; ++i) {
+        if (!DFGTrue())
+            result += o.f;
+    }
+    return result;
+}
+
+for (var i = 0; i < 1000; ++i) {
+    foo();
+    fullGC();
+}
+
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to