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>
Fri, 15 May 2015 21:11:39 +0000 (21:11 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 May 2015 21:11:39 +0000 (21:11 +0000)
commit8cc4ec47142abbcabffcfd2ccf34cbcc2fdcd468
treec7a0243717537a700d6a798e1d8c7bd3f4da1020
parent60e6c0c65f7ca6ac357dcc93b1574ac16b14a7f4
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.

* 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.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@184415 268f45cc-cd09-0410-ab3c-d52691b4dbfc
14 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]