Insert store barriers late so that IR transformations don't have to worry about them
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 18 May 2015 03:39:28 +0000 (03:39 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 18 May 2015 03:39:28 +0000 (03:39 +0000)
commit1406e0fcedb9c22db7b5e38a58919d914b74739b
treeb153a1ef3c01cbe90a7a223b369e03a7ca233638
parente096866a1dd4176cac65f31b07d790e7e8051c58
Insert store barriers late so that IR transformations don't have to worry about them
https://bugs.webkit.org/show_bug.cgi?id=145015

Reviewed by Geoffrey Garen.

We have had three kinds of bugs with store barriers. For the sake of discussion we say
that a store barrier is needed when we have something like:

    base.field = value

- We sometimes fail to realize that we could remove a barrier when value is a non-cell.
  This might happen if we prove value to be a non-cell even though in the FixupPhase it
  wasn't predicted non-cell.

- We sometimes have a barrier in the wrong place after object allocation sinking. We
  might sink an allocation to just above the store, but that puts it just after the
  StoreBarrier that FixupPhase inserted.

- We don't remove redundant barriers across basic blocks.

This comprehensively fixes these issues by doing store barrier insertion late, and
removing the store barrier elision phase. Store barrier insertion uses an epoch-based
algorithm to determine when stores need barriers. Briefly, a barrier is not needed if
base is in the current GC epoch (i.e. was the last object that we allocated or had a
barrier since last GC) or if base has a newer GC epoch than value (i.e. value would have
always been allocated before base). We do conservative things when merging epoch state
between basic blocks, and we only do such inter-block removal in the FTL. FTL also
queries AI to determine what type we've proved about value, and avoids barriers when
value is not a cell. FixupPhase still inserts type checks on some stores, to maximize
the likelihood that this AI-based removal is effective.

Rolling back in after fixing some debug build test failures.

* CMakeLists.txt:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* dfg/DFGBlockMap.h:
(JSC::DFG::BlockMap::at):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
* dfg/DFGEpoch.h:
(JSC::DFG::Epoch::operator<):
(JSC::DFG::Epoch::operator>):
(JSC::DFG::Epoch::operator<=):
(JSC::DFG::Epoch::operator>=):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::speculateForBarrier):
(JSC::DFG::FixupPhase::insertStoreBarrier): Deleted.
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThreadImpl):
* dfg/DFGStoreBarrierElisionPhase.cpp: Removed.
* dfg/DFGStoreBarrierElisionPhase.h: Removed.
* dfg/DFGStoreBarrierInsertionPhase.cpp: Added.
(JSC::DFG::performFastStoreBarrierInsertion):
(JSC::DFG::performGlobalStoreBarrierInsertion):
* dfg/DFGStoreBarrierInsertionPhase.h: Added.
* ftl/FTLOperations.cpp:
(JSC::FTL::operationMaterializeObjectInOSR): Fix an unrelated debug-only bug.
* tests/stress/load-varargs-then-inlined-call-and-exit.js: Test for that debug-only bug.
* tests/stress/load-varargs-then-inlined-call-and-exit-strict.js: Strict version of that test.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@184445 268f45cc-cd09-0410-ab3c-d52691b4dbfc
17 files changed:
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/dfg/DFGBlockMap.h
Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
Source/JavaScriptCore/dfg/DFGEpoch.h
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp
Source/JavaScriptCore/dfg/DFGPlan.cpp
Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
Source/JavaScriptCore/dfg/DFGStoreBarrierElisionPhase.cpp [deleted file]
Source/JavaScriptCore/dfg/DFGStoreBarrierInsertionPhase.cpp [new file with mode: 0644]
Source/JavaScriptCore/dfg/DFGStoreBarrierInsertionPhase.h [moved from Source/JavaScriptCore/dfg/DFGStoreBarrierElisionPhase.h with 61% similarity]
Source/JavaScriptCore/ftl/FTLOperations.cpp
Source/JavaScriptCore/tests/stress/load-varargs-then-inlined-call-and-exit-strict.js [new file with mode: 0644]
Source/JavaScriptCore/tests/stress/load-varargs-then-inlined-call-and-exit.js [new file with mode: 0644]